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

Requêtes MySQL Discussion :

Jointure sur 5 tables différentes


Sujet :

Requêtes MySQL

  1. #1
    Candidat au Club
    Inscrit en
    Janvier 2005
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2
    Par défaut Jointure sur 5 tables différentes
    Bonjour à tous,

    Je souhaite créer une base de données de films un peu kitsh pour un projet de VOD que je dois effectuer lors d'un projet d'école.

    J'ai donc 5 bases distinctes :

    - serial_films : base de films avec toutes les informations associées (description, acteurs etc.)

    - serial_origines : base d'intitulé d'origine des films (américain, français etc.)
    - serial_films_l_origines : base qui relie les id des films aux id des origines sachant qu'un film peut avoir plusieurs origines donc plusieurs rows par films

    - serial_genres : base d'intitulé des genres de films (action, aventure etc.)
    - serial_films_l_genres : base qui relie les id des films aux id des genres sachant qu'un film peut avoir plusieurs genres

    Mon but est de créer en une seule requête un tableau de résultat comprenant toutes les informations sur un film dont ses origines et ses genres associés. J'ai donc utilisé un GROUP CONCAT pour mettre en une row et séparés par des virgules les genres associés au film, jusque là tout est OK, voici la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT A.id, A.titre, A.jaquette, A.description, A.realisateur, A.acteurs, A.duree, A.annee, A.nb_vues, A.date_ajout, 	GROUP_CONCAT(C.intitule_genre SEPARATOR ', ' ) AS genre 
    		FROM serial_films A
    		INNER JOIN serial_films_l_genres B ON A.id = B.id_film 
    		INNER JOIN serial_genres C ON B.id_genre = C.id_genre_p  
    		GROUP BY A.id
    Elle marche parfaitement mais voilà, j'aimerai maintenant pouvoir ajouter à ce tableau de résultat, les origines associées donc si on suit le même schéma, on arrive à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT A.id, A.titre, A.jaquette, A.description, A.realisateur, A.acteurs, A.duree, A.annee, A.nb_vues, A.date_ajout, GROUP_CONCAT(C.intitule_genre 
    SEPARATOR ', ' ) AS genre, GROUP_CONCAT(E.intitule_origine 
    SEPARATOR ', ' ) AS origine 
    FROM serial_films A 
    INNER JOIN serial_films_l_genres B ON A.id = B.id_film 
    INNER JOIN serial_genres C ON B.id_genre = C.id_genre_p 
    INNER JOIN serial_films_l_origines D ON A.id = D.id_film 
    INNER JOIN serial_origines E ON D.id_origine = E.id_origine_p 
    GROUP BY A.id 
    LIMIT 0 , 30
    Tout marche nickel, j'ai bien toutes les informations que je veux. Néanmoins, la requête met 14 secondes à charger ce qui est énorme et j'ai un deuxième souci, si jamais il y'a plusieurs genres associés au film alors le champ origine contient plusieurs fois l'information à la suite. (ex : France, France, France...le nombre dépend du nombre de genres).

    Pensez-vous qu'il y'a un moyen de l'optimiser ? Si non, pensez-vous qu'il serait plus rentable d'effectuer 2 requêtes à la suite, une pour les genres et une pour les origines ? Sachant que chaque requête séparée prend environ 1 seconde.

    Qu'en pensez-vous ?

  2. #2
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Un film peut avoir plusieurs genres ?
    Que sont ces genres ?

    GROUP_CONCAT n'est pas une instruction de la norme SQL mais propre à MySQL pour faire de la mise en forme de données, de la cosmétique, qui n'est pas le boulot d'un SGBD mais celui de l'application qui utilise la BDD.

    Tu as donc découvert les limites de l'utilisation de cette instruction. GROUP_CONCAT contiendra autant d'éléments qu'il y a de lignes à grouper. Avec deux GROUP_CONCAT dont un ayant moins de valeurs différentes que l'autres, les informations seront répétées.

    Je serais même curieux de savoir ce que donnerait le groupage de 5 valeurs et de 2 valeurs :
    - (A, B, C, D, E) (1, 2, 1, 2, 1) ?
    - (A, B, C, D, E) (1, 1, 1, 1, 1) ?
    - (A, B, C, D, E) (2, 2, 2, 2, 2) ?
    - (A, B, C, D, E) (Euh...) ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Candidat au Club
    Inscrit en
    Janvier 2005
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2
    Par défaut
    Merci de ta réponse CinePhil, je ne conaissai pas du tout cette notion de "cosmétique" donc faut absolument que je trouve une solution intermédiaire on est daccord.

    Pour répondre à ta question, oui, un film peut être une comédie et un film d'aventure en même temps d'ou la table que j'ai crée qui relie les id_film aux id_genre

    Mais j'ai remarqué qu'organiser les tables de cette façon devient beaucoup plus fastidieux à l'utilisation au niveau du temps de traitement et de la taille des requêtes.
    Une simple colonne "genre" dans la table des films avec plusieurs genres dans la même case séparés par des pipes est tellement plus simple dans mon cas (ex:Aventure|Comédie|Action). Un petit traitement en PHP abouti au même résultat beaucoup plus rapidement.

    Je me doute que les experts SQL ne vont pas apprécier de voir plusieurs valeurs dans une même case donc si vous avez une solution plus "pro" pour aboutir au même résultat mais en full SQL, je suis preneur.

    Merci !

  4. #4
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Ceci :
    Une simple colonne "genre" dans la table des films avec plusieurs genres dans la même case séparés par des pipes est tellement plus simple dans mon cas (ex:Aventure|Comédie|Action). Un petit traitement en PHP abouti au même résultat beaucoup plus rapidement.
    me semble incompatible avec cela :
    je dois effectuer lors d'un projet d'école.
    parce que :
    Je me doute que les experts SQL ne vont pas apprécier de voir plusieurs valeurs dans une même case
    Effectivement, et normalement celui qui va noter ton projet !

    La solution pro est celle que tu as envisagée.
    Si tu as des problèmes de performance, vérifie la structure des tables :
    - identifiants de type entier non nul non signé autoincrémenté ;
    - clés étrangères faisant référence aux identifiants et donc de type entier non signé et si possible non nul.

    Vérifie aussi que les tables sont bien indexées :
    - Clé primaires en principe c'est automatique ;
    - Clés étrangères ça ne l'est pas forcément ;
    - Index supplémentaire sur la deuxième colonne d'une clé primaire double d'une table associative ;
    - Index sur les colonnes les plus interrogées dans les conditions WHERE (titre du film, libellé du genre, nom du pays...).
    Pour plus d'infos, voir l'article de SQLPro sur "quoi indexer ?"

    Si tu bloques sur certaines requêtes, montre-nous les et dis-nous où ça coince ; nous t'aiderons.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/10/2011, 15h51
  2. jointure sur des tables de DB différentes
    Par calison3 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 23/05/2007, 10h19
  3. Somme de 3 COUNT() sur 3 tables différentes
    Par PyRoFlo dans le forum Langage SQL
    Réponses: 9
    Dernier message: 13/08/2004, 18h36
  4. jointure sur TROIS tables
    Par caribou_belle dans le forum Langage SQL
    Réponses: 8
    Dernier message: 01/03/2004, 11h20
  5. Jointure sur 2 tables de bases différentes
    Par Celina dans le forum Langage SQL
    Réponses: 10
    Dernier message: 10/11/2003, 11h56

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