Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD
PHP & SGBD Forum d'entraide sur les SGBD avec PHP. Avant de poster : FAQ BDD, toutes les FAQ PHP, cours BDD et sources BDD
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/05/2006, 20h54   #1
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Par défaut [SQL] Requête SQL trop compliquée pour lui.

Bonjour,

Comme il se fait frapper par tout le monde parce qu'il programme pas dans les règles, il se dit qu'il va faire un effort pour son forum.
Mais c'est pas facile.
Il explique :

-Il a 100 définitions.
-Chaque définition comporte x commentaires.
-Il affiche un tableau avec toute la liste des définitions et en dessous de chacune, le titre du tout dernier commentaire posté pour cette définition.

Pour l'instant, il a fait un truc de sauvage :
Il insère à l'intérieur de la table définition, un champ titreComm. Lorsque quelqu'un poste un nouveau commentaire, le contenu et le titre du com partent dans la table commentaire et le titre part dans le champ titreComm de la table définition.
Donc ça défie les règles de la déontologie puisque il a des informations étrangères dans sa table définition.

Alors il peut faire une requête sql bien sur, mais ça va prendre plus de temps pour s'afficher (il sait il va encore se faire tirer dessus si il dit ça) mais surtout il sait pas la faire, la dite requête...

Donc il faudrait dire en langage sql :
Va chercher dans la table définition les champs noms et dates de toutes les définitions mais aussi pour chaque définition le titre et la date du dernier commentaire laissé pour cette définition...



Vous s'avez faire ?
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h02   #2
Expert Confirmé
 
Avatar de Eusebius
 
Inscription : avril 2003
Messages : 3 286
Détails du profil
Informations forums :
Inscription : avril 2003
Messages : 3 286
Points : 3 155
Points : 3 155
Si j'ai bien compris, une définition "correspond" à n commentaire.
Comment un champ dans la table des définitions peut-il décrire cette relation ? Il faudrait plutôt un champ dans la table des commentaires, qui pointe sur la clé de la définition à laquelle il est rattaché.
Eusebius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h12   #3
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Ah oui j'ai oublié de préciser que le champ idDef de la table commentaire est la clef étrangère puisqu' équivalent au champ id de la table définition. On est pas foutu quand même.
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h21   #4
Expert Confirmé
 
Avatar de Eusebius
 
Inscription : avril 2003
Messages : 3 286
Détails du profil
Informations forums :
Inscription : avril 2003
Messages : 3 286
Points : 3 155
Points : 3 155
mais pourquoi tu as un champ titreComm dans la table définitions ?
Eusebius est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h29   #5
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Parce que comme ça je fais:
Code :
SELECT nomDefinition, titreComm FROM definitions
Ce qui me permet de récupérer le nom de la définition dans la table définitions mais aussi le titre du dernier commentaire pour cette définition, le tout sans aucune jointure ou autre puisque tout est dans la même table.
Mais c'est incorrect puisque le titre du dernier commentaire pour une définition n'a rien à faire normalement dans la table définition (pour l'id correspondant bien sur, mais tout de même ça n'est pas sa place).
Surtout que je n'ai pas que le titre du dernier commentaire, mais aussi son url, le pseudo, la date etc... ce qui fait bon nombre de données étrangères à l'intérieur de la table définition. C'est crade.
Normalement on fait une requête sql avec jointure naturelle pour aller chercher le dernier commentaire pour chaque définition.

Mais là c'est trop compliqué pour moi comme requête.
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h31   #6
Membre chevronné
 
Avatar de Kioob
 
Olivier Bonvalet
Inscription : septembre 2004
Messages : 550
Détails du profil
Informations personnelles :
Nom : Olivier Bonvalet
Âge : 32
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : septembre 2004
Messages : 550
Points : 723
Points : 723
Envoyer un message via MSN à Kioob
Eusebius : ce champ correspondrait plutot à "titreDernierCommentaire".

Donc oui, psychoBob, d'un point de vue modélisation de données, c'est mal (tm). Mais là encore, ce champ "titreDernierCommentaire" peut être considéré comme un petit cache ; et la plupart des forums font pareil : dans la table "sujet", on retrouve souvent des champs "auteur_dernier_message", "date_dernier_message", ainsi que "nombre_de_message".

Pour la simple et bonne raison que de faire du GROUP BY et/ou requètes impriquées à répétition sur une page de forum, ça va pas tenir des lustres

----

EDIT : mais histoire de rendre ça un peu plus propre tu peux éventuellement ajouter un champ "id_dernier_commentaire", ce qui fera moins de redondance de données et sera donc plus simple à maintenir.
Toutefois malgré la jointure la requête restera simple et relativement rapide.
__________________
Google is watching you !
Kioob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h38   #7
Membre Expert
 
Inscription : juillet 2004
Messages : 1 033
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 1 033
Points : 1 050
Points : 1 050
Perso je n'ai rien trouvé de mieu que deux sous requetes... une autre idée ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
SELECT 
     nomDef,
      (
          SELECT titre 
          FROM commentaires c 
          WHERE c.idDef=d.id 
          ORDER BY c.id DESC 
          LIMIT 0,1
     ) 
     As LastTitre, 
     (
          SELECT madate 
          FROM commentaires c 
          WHERE c.idDef=d.id 
          ORDER BY c.id DESC 
          LIMIT 0,1
     ) 
     As LastDate  
FROM def d
ePoX est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h39   #8
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Ah bah ça fait plaisir de lire que mon code est pas le plus indigeste qui soit et que les bons ou pas mauvais font comme ça aussi.

Citation:
EDIT : mais histoire de rendre ça un peu plus propre tu peux éventuellement ajouter un champ "id_dernier_commentaire", ce qui fera moins de redondance de données et sera donc plus simple à maintenir.
Toutefois malgré la jointure la requête restera simple et relativement rapide.
Ah l'idée est bonne, il me semblait bien qu'il y avait un truc à faire dans le genre, bien vu Kioob

Bon je vais laisser comme ça pour le moment, si mon forum est trop plein à craquer, ça sera pas la mort à changer je pense.
J'ai tort ?
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h40   #9
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Citation:
Envoyé par ePoX
Perso je n'ai rien trouvé de mieu que deux sous requetes... une autre idée ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
SELECT 
     nomDef,
      (
          SELECT titre 
          FROM commentaires c 
          WHERE c.idDef=d.id 
          ORDER BY c.id DESC 
          LIMIT 0,1
     ) 
     As LastTitre, 
     (
          SELECT madate 
          FROM commentaires c 
          WHERE c.idDef=d.id 
          ORDER BY c.id DESC 
          LIMIT 0,1
     ) 
     As LastDate  
FROM def d
Aïe voilà Mr ePoX, qui va me faire changer d'avis...
M'enfin ceci dit c'est intéressant mais comme dis Kioob et comme je le craignais, ce genre de requête doit grignoter pas mal de ressources...
Vous en pensez quoi les autres ?
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h43   #10
Membre chevronné
 
Avatar de Kioob
 
Olivier Bonvalet
Inscription : septembre 2004
Messages : 550
Détails du profil
Informations personnelles :
Nom : Olivier Bonvalet
Âge : 32
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : septembre 2004
Messages : 550
Points : 723
Points : 723
Envoyer un message via MSN à Kioob
Moi j'en pense que mon forum n'a pas tenu 1 mois comme ça

C'est bien beau la théorie, mais y a des fois où le SGBD n'est pas d'accord... (et c'est loin d'être propre à MySQL hein)
__________________
Google is watching you !
Kioob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h47   #11
Membre Expert
 
Inscription : juillet 2004
Messages : 1 033
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 1 033
Points : 1 050
Points : 1 050
Comme dit kioob la théorie c'est bien beau. Après il faut savoir faire des entorces pour les performances.

La requete que j'ai posté c'était juste parcequ'en titillant le problème je me suis rendu compte que mon idée de départ ne fonctionnait pas (jointure toute bete avec order by). Donc j'ai un peu chercher par plaisir.

Ceci dit, personne ne voit d'autres solutions ?
ePoX est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h48   #12
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Citation:
Moi j'en pense que mon forum n'a pas tenu 1 mois comme ça
Comprenons nous bien, tu parles de quoi ? des données imbriquées comme je fais ou des requêtes sql plus complexes ?

**edit** je regarde un peu ta requête ePoX mais ça donnerait un truc abominable , car je récupère 6 champs de la table def et 4 de la table commentaire...
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h57   #13
Membre chevronné
 
Avatar de Kioob
 
Olivier Bonvalet
Inscription : septembre 2004
Messages : 550
Détails du profil
Informations personnelles :
Nom : Olivier Bonvalet
Âge : 32
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : septembre 2004
Messages : 550
Points : 723
Points : 723
Envoyer un message via MSN à Kioob
Je parles des requêtes SQL complexes.

Sur mon forum ça donnait quelque chose comme ça :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
select s.titre, s.auteur, t.nb_message,
    m.auteur as auteur_dernier_message,
    m.date_modification as date_dernier_message
from forum_sujet s,
    (
        select id, max( m.id ) as id_dernier_message, count(*) as nb_message
        from forum_sujet s, forum_message m
        where s.categorie = 5
        and s.id = m.id_sujet
        group by s.id
    ) t,
    forum_message m
where s.id = t.id
and t.id_dernier_message = m.id
order by m.date_modification desc;
Effectivement il n'y avait aucune redondance dans la base de données... mais c'était une horreur.



Edit : en plus à l'époque j'étais en MySQL 3, donc fallait faire ça en deux fois...
__________________
Google is watching you !
Kioob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 21h59   #14
Membre Expert
 
Inscription : juillet 2004
Messages : 1 033
Détails du profil
Informations forums :
Inscription : juillet 2004
Messages : 1 033
Points : 1 050
Points : 1 050
Citation:
**edit** je regarde un peu ta requête ePoX mais ça donnerait un truc abominable , car je récupère 6 champs de la table def et 4 de la table commentaire...
Je sais bien, et puis les perf de m**** aussi. Je ne saurait trop te conseiller de suivre ceci ecrit quelques post plus haut :

Citation:
Envoyé par kioob
EDIT : mais histoire de rendre ça un peu plus propre tu peux éventuellement ajouter un champ "id_dernier_commentaire", ce qui fera moins de redondance de données et sera donc plus simple à maintenir.
Toutefois malgré la jointure la requête restera simple et relativement rapide.
ePoX est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 22h04   #15
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Euh... une idée pour la requête de Kioob ?

J'oserais bien :

Code :
1
2
3
4
Select definitions.nomDef, commentaires.titre 
FROM definitions,commentaires
 WHERE definitions="'.$lettre.'" 
AND commentaires.id=definitions.id_dernier_commentaire
C'est ça à vue de nez ou j'ai raté un truc ?
Vous pensez vraiment que ça en vaut la peine ? Finalement j'ai plus qu'un champ étranger à la table au lieu de 4 mais bon qu'est ce que ça change à part me faire retravailler mes scripts ?
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 22h10   #16
Membre chevronné
 
Avatar de Kioob
 
Olivier Bonvalet
Inscription : septembre 2004
Messages : 550
Détails du profil
Informations personnelles :
Nom : Olivier Bonvalet
Âge : 32
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : septembre 2004
Messages : 550
Points : 723
Points : 723
Envoyer un message via MSN à Kioob
A priori oui, ce serait ça.

Parmis les avantages par rapport à ton code actuel :
- cela évite la redondance (donc tables plus petites, ce qui implique souvent traitement légèrement plus rapide)
- cela facilite la maintenance puisqu'ill n'y a plus qu'un seul champ à maintenir à jour

Mais le plus gros inconvénient, c'est que maintenant tu as une jointure... ce qui n'était pas le cas avant...

Après, à toi de trouver un juste milieu.
__________________
Google is watching you !
Kioob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 22h16   #17
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Bon, je garde tout ça sous la main, c'était important d'en parler ça me permet de mieux prendre conscience de mon site, de ses évolutions et problèmes éventuels...

Mais en attendant ça va rester comme ça, j'ai plus important à faire dans l'immédiat vu que ça n'est pas une catastrophique faute de programmation au vu de ce que vous me dites.

Merci à tous


**edit** question quand même : quand tu dis que la jointure est le plus gros inconvénient, c'est uniquement en matière de temps d'exécution ou il y a un truc caché en plus ? (je vois pas quoi mais bon).
Cette jointure elle peut demander combien de temps d'exécution en plus par rapport à une requête sur une seule table ?
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 22h31   #18
Membre chevronné
 
Avatar de Kioob
 
Olivier Bonvalet
Inscription : septembre 2004
Messages : 550
Détails du profil
Informations personnelles :
Nom : Olivier Bonvalet
Âge : 32
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : septembre 2004
Messages : 550
Points : 723
Points : 723
Envoyer un message via MSN à Kioob
La jointure est "plus lente", qu'une lecture simple. De combien, impossible à savoir : cela dépend de la taille des tables, des indexes, de la configuration de MySQL, etc. Bref, rien de standard de ce coté.
D'un autre coté, une jointure ce n'est pas forcément catastrophique non plus : après tout les SGBD sont fait pour.
__________________
Google is watching you !
Kioob est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/05/2006, 22h52   #19
Membre éclairé
 
Inscription : juillet 2005
Messages : 1 221
Détails du profil
Informations forums :
Inscription : juillet 2005
Messages : 1 221
Points : 398
Points : 398
Citation:
Je parles des requêtes SQL complexes.

Sur mon forum ça donnait quelque chose comme ça :
Code :
[LEFT]select s.titre, s.auteur, t.nb_message, m.auteur as auteur_dernier_message, m.date_modification as date_dernier_messagefrom forum_sujet s, ( select id, max( m.id ) as id_dernier_message, count(*) as nb_message from forum_sujet s, forum_message m where s.categorie = 5 and s.id = m.id_sujet group by s.id ) t, forum_message mwhere s.id = t.idand t.id_dernier_message = m.idorder by m.date_modification desc;[/LEFT]
lol, même si j'avais su faire une requête pareille j'aurais jamais osé la mettre en ligne je crois. Autant monter à l'assaut avec un tracteur
__________________
C'est pas parce que j'ai tort que vous avez raison.
psychoBob est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h11.


 
 
 
 
Partenaires

Hébergement Web