Bonjour,

J'ai l'intention de créer un site (en local) qui me permettra de regrouper la liste des films que je possède dans ma vidéothèque.

J'hésite encore entre récupérer les informations via IMDB ou allociné. Mais mon problème se trouve plutôt au niveau de "l'architecture" de ma base de donnée.

Pour stocker le titre, le synopsis etc.. je pense que les stocker directement dans ma table movies est la bonne façon de faire.

Par contre, un film peut avoir plusieurs :

  • Nationalités
  • Genres
  • Acteurs

Du coup je pensais crée les tables :

  • nationalities (avec les champs : id, name)
  • genres (avec les champs : id, name)
  • actors (avec les champs : id, firstname, lastname, etc...)

Ensuite créer des tables pour pouvoir relier les tables ci-dessus à mes films :

  • movie_has_nationalities (id, movie_id, nationality_id)
  • movie_has_genres (id, movie_id, genre_id)
  • movie_has_actors (id, movie_id, actor_id)

Et c'est la ou je suis complètement perdue car je ne sais pas si c'est une bonne façon de faire et je ne sais pas non plus si c'est possible de récupérer grâce à une requête toutes les informations d'un coup et de les retourner d'un tableau du type :

array [
    'title' => 'titre du film',
    'synopsis' => 'le synopsis',
    // etc... 
    'nationalities' => [
        0 => [
            'id' => 'Son id',
            'name' => 'Le nom de la nationalité',
        ], 
        // Et les autres, si il y en a d'autres
    ],
    'genres' => [
        0 => [
            'id' => 'Son id',
            'name' => 'Le nom du genre',
        ], 
        // Et les autres, si il y en a d'autres
    ], 
    'actors' => [
        0 => [
            'id' => 'Son id',
            'firstname' => 'firstname',
            'lastname' => 'lastname',
            // etc..
        ], 
        // Et les autres, si il y en a d'autres
    ], 
]

Ou suis-je obligés de faire plusieurs requêtes ? Je sais faire des JOINTURE simple du style relier une catégorie (une seule) à un film mais je ne sais pas si c'est possible avec plusieurs valeurs :(

Merci d'avance pour votre aide ;)

11 réponses


eltharin
Réponse acceptée

Bonjour,
voici la requete à utiliser je pense :

SELECT m.id, m.title, m.synopsis, g.name AS genres, n.name AS nationalities, GROUP_CONCAT(DISTINCT g.name ORDER BY g.name DESC SEPARATOR ' ,') AS genres, GROUP_CONCAT(DISTINCT n.name ORDER BY n.name DESC SEPARATOR ',') AS nationalities
FROM movies AS m
LEFT JOIN movies_has_genres AS mg ON mg.movie_id = m.id
LEFT JOIN genres AS g ON g.id = mg.genre_id
LEFT JOIN movies_has_nationalities AS mn ON mn.movie_id = m.id
LEFT JOIN nationalities AS n ON n.id = mn.nationality_id
WHERE m.id = 7
GROUP BY genres, nationalities

ca te fera une seule valeur avec tous les genres séparés par des virgules et toutes les nationalités IDEM.
En épérant que ca t'aide.

Bonsoir.
C'est tout a fait possible, je te recommande de visualiser par exemple Tutoriel Vidéo Mysql » Les jointures MySQL.

sheila
Auteur

Bonjour Lartak et merci de ta réponse :)

J'ai créer les tables et essayer de faire une requete pour le moment en reliant seulement les genres et les nationalités car c'est difficile pour moi :

SELECT m.id, m.title, m.synopsis, g.name AS genres, n.name AS nationalities
FROM movies AS m
LEFT JOIN movies_has_genres AS mg ON mg.movie_id = m.id
LEFT JOIN genres AS g ON g.id = mg.genre_id
LEFT JOIN movies_has_nationalities AS mn ON mn.movie_id = m.id
LEFT JOIN nationalities AS n ON n.id = mn.nationality_id
WHERE m.id = 7

Cette requête me retourne les lignes de cette façon :

id      title               synopsis                            genres              nationalities
7       Titre N°1       Synopsis du film N°1      Fantastique     Américaine
7       Titre N°1       Synopsis du film N°1      Aventure          Américaine
7       Titre N°1       Synopsis du film N°1      Fantastique     Française
7       Titre N°1       Synopsis du film N°1      Aventure          Française

Mais du coup les genres et les nationalités sont retourné 2 fois, est ce que je m'y prends bien ? Et si oui alors comment évité de repété les champs dejà retourné ?

sheila
Auteur

Je me permet de up le sujet, quelqu'un peut m'aider ?

Bonsoir, si tu veux éviter les répétitions il peut être utile de faire usage de "GROUP BY genres" par exemple.

sheila
Auteur

Lorsque que je fais un group by avec genres ça me retourne :

id      title               synopsis                            genres              nationalities
7       Titre N°1      Synopsis du film N°1     Aventure               Américaine
7       Titre N°1      Synopsis du film N°1     Fantastique          Américaine

Du coup c'est bon pour les genres mais les nationalités, j'ai 2 fois Américaine alors que je voudrais (pour cet exemple) Américaine et Française. J'ai essayé d'ajouté nationalities dans mon group by mais plus rien n'est retourné :(

Merci de votre aide :)

As-tu essaye de faire un

GROUP BY genres, nationalities; 

? Par contre je pense qu'il faut utiliser une fonction d'aggregat pour compter le nombres d'occurences dans chaque groupe de maniere a ce qu'il te retourne un resultat correct :)

sheila
Auteur

Oui j'ai bien essayé d'ajouté le group by que tu proposes :) (par contre dans mon précédent post je disais que sa ne retourné rien alors que si)
Ca me retourne :

id      title               synopsis                            genres              nationalities
7       Titre N°1      Synopsis du film N°1     Aventure          Américaine
7       Titre N°1      Synopsis du film N°1     Aventure          Française
7       Titre N°1      Synopsis du film N°1     Fantastique     Américaine
7       Titre N°1      Synopsis du film N°1     Fantastique     Française

Une fonction aggregat qu'est ce que c'est ? C'est les fonctions du type count(), max() etc.. ? Si oui alors j'ai essayé ceci mais je ne sais pas du tout si je l'utilise correctement

SELECT m.id, m.title, m.synopsis, g.name AS genres, n.name AS nationalities, COUNT(g.name) AS nbgenres, COUNT(n.name) AS nbnationalities
FROM movies AS m
LEFT JOIN movies_has_genres AS mg ON mg.movie_id = m.id
LEFT JOIN genres AS g ON g.id = mg.genre_id
LEFT JOIN movies_has_nationalities AS mn ON mn.movie_id = m.id
LEFT JOIN nationalities AS n ON n.id = mn.nationality_id
WHERE m.id = 7
GROUP BY genres, nationalities

Ca me retourne :

id      title               synopsis                            genres              nationalities       nbgenres        nbnationalities
7       Titre N°1      Synopsis du film N°1     Aventure          Américaine    1   1
7       Titre N°1      Synopsis du film N°1     Aventure          Française     1   1
7       Titre N°1      Synopsis du film N°1     Fantastique     Américaine  1   1
7       Titre N°1      Synopsis du film N°1     Fantastique     Française   1   1

Merci pour votre aide :)

As-tu essaye

GROUP BY g, n;
sheila
Auteur

Je viens d'essayé est j'obtiens l'erreur : #1054 - Champ 'g' inconnu dans group statement mais c'est normal puisque g et n son les alias de mes tables genres, et nationalities non ?

sheila
Auteur

Bonjour

J'avais essayé quelques choses du genre mais j'ai du faire des erreurs quelques part car je n'obtenais pas le même resultat que ta requete.
Un grand merci pour ton aide (ou comme j'ai copier coller, merci plutôt pour la solution) :)