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

  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.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  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
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  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 ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  7. #7
    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
    Parce qu'il me sélectionne les (par exemple) 20 premiers résultats de la première table utilisée :/

  8. #8
    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
    Tu as bien mis un ORDER BY ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  9. #9
    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
    Un problème intervenait dans la dénomination des champs, j'ai donc résolu ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (SELECT i_id AS id, i_time AS time, i_titre AS titre, i_cat AS cat, cat_id, cat_nom FROM lpdn_images, lpdn_categories WHERE i_cat = cat_id AND i_actif = 1 ) UNION
    (SELECT v_id AS id, v_time AS time, v_titre AS titre, v_cat AS cat, cat_id, cat_nom FROM lpdn_videos, lpdn_categories WHERE v_cat = cat_id AND v_actif = 1 ) UNION
    (SELECT s_id AS id, s_time AS time, s_titre AS titre, s_cat AS cat, cat_id, cat_nom FROM lpdn_sites, lpdn_categories WHERE s_cat = cat_id AND s_actif = 1 ) UNION
    (SELECT a_id AS id, a_time AS time, a_titre AS titre, a_cat AS cat, cat_id, cat_nom FROM lpdn_articles, lpdn_categories WHERE a_cat = cat_id AND a_actif = 1 )
    ORDER BY time DESC LIMIT 20
    Le problème maintenant c'est que je ne peux plus récupérer le type de l'entrée :/ comment savoir si c'est une vidéo, une image ou autre ?

  10. #10
    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
    Tu peux ajouter un champ fixe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (SELECT "image" as type,i_id AS id, i_time AS time etc.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  11. #11
    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
    Ah, je connaissais pas cette astuce, merci !
    Voici donc la requête finale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (SELECT "image" AS type, i_id AS id, i_time AS time, i_titre AS titre, i_cat AS cat, cat_id, cat_nom FROM lpdn_images, lpdn_categories WHERE i_cat = cat_id AND i_actif = 1 ORDER BY time DESC LIMIT 20) UNION
    (SELECT "video" AS type, v_id AS id, v_time AS time, v_titre AS titre, v_cat AS cat, cat_id, cat_nom FROM lpdn_videos, lpdn_categories WHERE v_cat = cat_id AND v_actif = 1 ORDER BY time DESC LIMIT 20) UNION
    (SELECT "site" AS type, s_id AS id, s_time AS time, s_titre AS titre, s_cat AS cat, cat_id, cat_nom FROM lpdn_sites, lpdn_categories WHERE s_cat = cat_id AND s_actif = 1 ORDER BY time DESC LIMIT 20) UNION
    (SELECT "article" AS type, a_id AS id, a_time AS time, a_titre AS titre, a_cat AS cat, cat_id, cat_nom FROM lpdn_articles, lpdn_categories WHERE a_cat = cat_id AND a_actif = 1 ORDER BY time DESC LIMIT 20)
    ORDER BY time DESC LIMIT 20
    EDIT : J'ai oublié, (honte à moi), merci de ton aide !

    Dernière qestion, penses-tu vraiment qu'on gagnerait à rassembler les tables ? Au niveau performance surement mais au niveau modularité :/ Qu'en penses-tu ?

  12. #12
    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
    Justement avec ta structure actuelle tu n'es pas flexible : si tu devais ajouter une rubrique, tu devrais ré-ecrire tes requetes existantes et ajouter des requetes pour ta nouvelle rubrique.

    En enregistrant tes données de manière uniforme, tu peux ajouter des articles dans ta base avec une nouvelle rubrique sans rien modifier au code et ils apparaitront dans ta presentation avec les autres.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  13. #13
    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
    Dans le big tuto que j'ai lu sur le SELECT de SQL ici, ils parlent entre autre des schéma SQL pour les requête, et disent que la clause WHERE est une clause qui est effectué après la construction du plan, et donc que tous les éléments sont d'abord sélectionné, puis ensuite trié, donc au niveau performance, le temps de la requête sera le même avec ou sans le where je me trompe ? Du coup rassembler les tables ralongerait le temps de la requête non ?

    Date : 27 Dec 2002 10:17:10 +0100
    De : Frédéric BROUARD
    La clause WHERE est un filtre d'élimination. Il suppose que les différentes tables sont déjà jointes en une seule et parcoure l'ensemble des résultats à la recherche des lignes correspondant aux critères donnés.
    En revanche la clause JOIN se comporte différemment. Elle agit AVANT
    que la jointure soit effective.
    [...]

  14. #14
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    sur la performance, réponse ici : http://www.developpez.net/forums/d66...s/#post3914563

    Sur la modélisation et l'évolutivité, 100% d'accord avec Sabotage !
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  15. #15
    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
    Merci de cette réponse illuminatrice

+ 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