Gestion intelligente de multiples jointures externes 0…n

WRInaute impliqué
Je me pose une question sur la meilleure façon de traiter de multiples jointures externes de cardinalité 0…n.

Pour clarifier la question, une mise en conditions, mettons qu'il s'agisse de gérer des activités avec des animateurs des participants.
Une table enregistre les activités, une ligne, par activité,
Une table enregistre les animateurs, une ligne par animateur,
Une table enregistre les participants, une ligne par participant.
Enfin, une table met en relation les animateurs affectés sur une activité (chaque ligne est un couple clé primaire de l'activité / clé primaire d'un animateur, plus quelques autres données) et une autre les participants inscrits sur l'activité (même principe).
Tout ça me paraît sain d'un point de vue de conception de BDD.

Je n'ai pas de difficulté pour ressortir la liste des animateurs d'une activité, une première jointure 0…n avec la table de relation des animateurs, puis une jointure 1…1 avec la table des animateurs. Pas de difficulté non plus pour ressortir la liste des participants.

Là où je m'interroge, c'est que, finalement, je pourrais, lors d'une même requête tout récupérer. Le problème c'est que le résultat sera variable, parfois j'ai plus d'animateurs que de participants (à l'ouverture des inscriptions), et donc un des participants sera "répété", et parfois ce sera l'inverse (un animateur sera répété).

Après, je peux très bien traiter ça en parcourant les résultats et en pointant les clé primaire : si c'est une clé primaire inconnue pour un participant, j'ajoute le participant, si je connais déjà cette clé primaire, c'est une répétition.

Donc c'est faisable. La question c'est plutôt est-ce efficient ?

D'un côté je fais une requête plutôt que trois (une pour les données de l'activité, une pour les animateurs, une pour les participants).
D'un autre je récupère beaucoup de données inutiles (répétées), et fait faire pas mal de jointures. Par ailleurs ça fait des requêtes un peu compliquées.

J'ai tendance à éviter le nombre de requêtes, mais est-ce la bonne pratique ?
 
WRInaute passionné
Dans ce genre de cas, donc pour afficher 1 activité précise, je ferais bien 3 requêtes.
On utilise le minimum de mémoire, et évite les jointures qui ont un coût aussi, en tout cas avec MySQL je fais comme ça.
Vous pouvez vérifier les perfs en testant les deux cas (microtime() en PHP pour prende le temps à la microseconde).

Par contre pour une vue où on afficherait toutes les activités, avec pour chacune tous ses animateurs et participants, je ne ferais pas 2 requêtes pour chaque activité, après la requête sortant toutes les activités, je ferais en sorte que les 2 autres requêtes sortent tous les participants et animateurs triés par id de l'activité puis par le code une boucle pour afficher pour chaque activité ses participants et animateurs. 3 requêtes pour une page ça va, par contre 30, non...

Mais je me suis fait un système de cache en fait, je stocke le résultat des requêtes, que je recharge tant que la table n'a pas été modifée, parce que par moments j'avais trop d'accès à la base et elle était lente. Donc 1 ou 3 requêtes dans ce cas-ci pas beaucoup de différence de perf.
 
Dernière édition:
WRInaute impliqué
Compliqué tant que je n'ai pas les données réelles de vraiment simuler la différence de temps de traitement malheureusement… et le temps de traitement avec des jointure ne se fait vraiment sentir que quand la base commence à grossir sérieusement.

J'avais commencé à coder avec une seule requête, et puis j'ai repris mon code ce matin pour en faire trois… Ce qui m'a décidé c'est du code plus lisible, et puis la possibilité d'utiliser la même fonction : pour éviter de faire des requêtes de partout, je créée une fonction qui fait les appels en base de donnée et retourne les résultats avec quelques traitements (ce qui m'évite aussi de manipuler les noms de colonnes dans tout le code). Là, je peux mettre un paramètre dans l'appel à la fonction pour ne consulter que la table activité, et éventuellement la compléter par celles des animateurs et / ou celle des participants.

Et tu as raison dans le fond, une ou trois requêtes ça change pas grand chose… Dans le cas d'un appel sur plusieurs activités je n'ai pas besoin du détail des animateurs ou des participants, mais juste parfois de leur nombre, et ça je peux parfaitement l'obtenir par une jointure sur une sous-requête.
 
Discussions similaires
Haut