IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Conseil sur traitement des données [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 215
    Points : 171
    Points
    171
    Par défaut Conseil sur traitement des données
    Bonjour,

    Présentation brève du site

    Je suis actuellement en train de recoder un certains aspect d'un site (MP pour avoir l'adresse). Sur ce site, la page d'accueil affiche une liste des 20 derniers éléments ajoutés au site, avec une pagination pour remonter dans le temps. Ces éléments se partagent en différents types : images, articles, dossiers, vidéos et sites.

    Introduction à l'organisation interne du site

    La base de donnée est organisé ainsi : 2 tables par type : une qui contient l'id, le titre, la date (format timestamp), le lien vers le media contenu (nom du fichier image par exemple), et id de la sous-catégorie il appartient. L'autre table contient l'id, l'id de l'élément auquel elle se rapporte, et le commentaire ou la description du contenu par celui qui a posté l'élément. Chaque première table a deux index : un sur l'id, et un sur le titre, utilisé pour la recherche fulltext.

    La problématique


    Pour pouvoir lister les 20 derniers éléments, on est obligé de sélectionner TOUT les enregistrements, pour les trier par date. Pourquoi tous les prendre au lieu de faire un petit LIMIT 0,20 ? Eh bien, si je ne prends pas tous les éléments, impossible de faire une pagination !! Un exemple pour mieux comprendre :

    Les 18 derniers éléments sont des vidéos, j'affiche donc les 18 dernières vidéos, puis les 2 images qui ont été enregistrées après. Lorsque je vais sur la page 2, le "LIMIT" de ma requête devient 20,20 ! Donc je passe à côté de toutes les images de 2 à 20 !

    Le problème est la pagination, cependant il n'est pas envisagé de la supprimer.

    J'ai donc pensé qu'en utilisant les jointures internes, je pourrais résoudre mon problème, mais la taille de la requête actuelle est déjà un beau morceau pour moi, alors si en plus je dois me coller les jointures .... J'avoue que j'ai besoin d'un coup de main !

    Pour concrétiser un peu la chose, voici la requête actuelle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    $nbre_ligne_par_page = 20;
     
    	if(empty($_GET['page'])) { $page = 1; }
    	else { $page = intval($_GET['page']); }
    	$debut = ($page - 1)*$nbre_ligne_par_page;
    	$fin = $page*$nbre_ligne_par_page;
     
    $type = htmlentities($_GET['typ']);
     
    if(!empty($type)){
     
    	$liste_type = array($type.'s');
    }
    // $liste_type est défini dans include/config.php
    foreach($liste_type AS $each){
     
    $prefixe = $each[0];	
    $data = mysql_query('SELECT '.$prefixe.'_id, '.$prefixe.'_time, '.$prefixe.'_titre, '.$prefixe.'_cat, '.$prefixe.'_actif, cat_id, cat_nom FROM lpdn_'.$each.', lpdn_categories WHERE '.$prefixe.'_cat = cat_id AND '.$prefixe.'_actif = 1 ');
    while($value = @mysql_fetch_assoc($data)){
     
    	$liste[$i]['id'] = $value[$prefixe.'_id'];
    	$liste[$i]['type'] = substr($each,0,-1);
    	$liste[$i]['time'] = $value[$prefixe.'_time'];
    	$liste[$i]['titre'] = $value[$prefixe.'_titre'];
    	$liste[$i]['cat'] = $value['cat_nom'];
    	$i++;
    }
    }
     
    foreach ($liste as $key => $row) {
        $temps[$key]  = $row['time'];
    }
     
    array_multisort($temps, SORT_DESC, $liste);
    $liste = array_splice($liste,0,$nbre_ligne_par_page);
     
    foreach($liste AS $value){ /* Listing des éléments dans un tableau */ }
    Le problème est bien évidemment que pour le moment, le contenu du site n'est pas exorbitant donc c'est gérable, mais une fois que le contenu va augmenter, récupérer toute la base ne sera pas envisageable.

    Une idée sur une issue possible ?

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    L'erreur est au départ d'avoir stocké des elements identiques dans des tables differentes.

    Tu dois pouvoir faire une UNION des tes 5 requetes et y appliquer le LIMIT.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 215
    Points : 171
    Points
    171
    Par défaut
    J'ai bien pensé réunir les tables en une seule, mais il y a quelques variantes, par exemple, lorsque nous rédigeons un article, on indique la source, ce qui n'est pas le cas pour une image, en contre-partie, pour une image nous indiquons le nom du fichier, on aurait pu faire un champ "extra" c'est vrai...

    En fait à la base, les tables on étaient séparées pour accélérer le traitement, en effet, si sur la page d'accueil on effectue un listing multi-type, il existe des pages consacrées "images", "vidéos" qui listent uniquement les éléments tu type concerné, j'ai donc pensé que le traitement serait amélioré sur on séparé les éléments. Il faut donc que je regroupe toutes les tables en une ?
    De plus, les commentaires (pour images vidéos et sites) et les contenus des articles et dossiers ont étaient séparés, on pourrait donc suivre le même raisonnement et les rassembler, le problème est que la table pour les dossiers contient également les numéros de page du dossier, qu'on pourrait assimiler aux chapitres. Il est donc problématique de tout rassembler.

    Avant les articles et les dossier étaient rassembler dans un seul type, et on les distinguer grâce à un champ "ac_page", mais il fallait faire une autre quête, pour compter le nombre d'entrée avec comme id l'id de l'article pour avoir le nombre de page et déterminer s'il s'agit d'un article ou non, ça posé des problèmes notament lorsque j'ai voulu réaliser une navigation "article suivant, article précédent", puisqu'il fallait naviguer dans les id de la table mais sans prendre en compte ceux des dossiers par exemple, le bordel !!

    J'ai exporté la structure de la BDD pour ceux que ça intéresse : http://dl.free.fr/q2vOlJQ5F

    Une autre question concernant les commentaires postés par les visiteurs, si on se met à regrouper toutes les tables, on pourrait regrouper les commentaires dans la même table, dans un champ, et on utiliserait un explode() sur le l'entrée pour récupérer les informations sur le membre qui a posté ainsi que le com, mais je ne trouve pas ça très modulaire :/

    Qu'en pensez-vous ? Merci de m'accorder du temps

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Pour les commentaire tu peux avoir une table tout simple :
    id - article_id - user_id - texte

    As-tu essayé de faire des UNION lorsque tu as besoin de piocher dans plusieurs tables ?

    SInon concernant le rassemblement, tu peux sois effectivement avoir des champs "extras" qui contiennent des choses differentes selon le type ou sois avoir des champs définis "chemin" mais pas toujours utilisés selon le type

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 215
    Points : 171
    Points
    171
    Par défaut
    Pour les commentaires, on procède déjà comme ça.

    Pour le union, ça ne fonctionne pas.

    Le problème d'un éventuel champ extra c'est pour la taille du champ. Elle sera très variable, puisqu'elle pourra contenir un simple lien, ou un dossier entier ! Le type du champ devra donc être de type text, ce qui n'est pas super, mais bon .

  6. #6
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Pourquoi ca ne fonctionne pas les UNION ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Traitement des données sur une checkbox - Formulaire
    Par kenjiendo dans le forum PHP & Base de données
    Réponses: 14
    Dernier message: 08/08/2011, 11h35
  2. Réponses: 22
    Dernier message: 02/02/2009, 20h36
  3. [Formulaires] Traitement des données dans une autre page...
    Par sekiryou dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 04/03/2006, 09h08
  4. [PHP-JS] Traitement des données dans une autre page...
    Par sekiryou dans le forum Langage
    Réponses: 5
    Dernier message: 04/03/2006, 09h06
  5. traitement des données avant envoie dans MySQL
    Par italiasky dans le forum SQL Procédural
    Réponses: 13
    Dernier message: 07/02/2006, 22h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo