web-dev-qa-db-fra.com

Relations multiples MySQL avec FOREIGN KEYS

J'essaie de créer une relation plusieurs à plusieurs dans ma base de données MySQL. J'ai trois tables: Films, Genres et Films_Genres. J'utilise le code suivant pour les configurer: 

CREATE TABLE Films
(  
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),   
    Title VARCHAR(255)
),  

CREATE TABLE Genres
(  
    id INT NOT NULL AUTO_INCREMENT,   
    PRIMARY KEY(id),  
    Name VARCHAR(255)
),

CREATE TABLE Films_Genres
(
    film_id INT NOT NULL,  
    genre_id INT NOT NULL,  
    PRIMARY KEY (film_id, genre_id),  
    FOREIGN KEY (film_id) REFERENCES Films(id) ON UPDATE CASCADE,  
    FOREIGN KEY (genre_id) REFERENCES Genres(id) ON UPDATE CASCADE
)  

Cependant, lorsque j'essaie d'insérer des valeurs dans les tableaux avec:

INSERT INTO Films (Title) VALUES ('$title')
INSERT INTO Genres (Name) VALUES ('$genre')

Je peux voir le nouveau film dans la table Films et le nouveau genre dans la table Genres mais La table Films_Genres ne se met pas à jour - il n'y a pas de nouvelles lignes (je vérifie via phpMyAdmin).

Qu'est-ce que je fais mal?

10
Sharkz

Vous ne verrez rien dans la table Films_Genres tant que vous n’y insérez pas explicitement quelque chose. L’intégrité référentielle par PK et FK ne permet pas de remplir vos tables à votre place.

Votre code MySql pour l'insertion d'un nouvel enregistrement dans Films_Genres, s'il s'agit d'un nouveau film correspondant à un nouveau genre, peut ressembler à

INSERT INTO Films (Title) VALUES ('Title1');
SET @film_id = LAST_INSERT_ID();

INSERT INTO Genres (Name) VALUES ('Genre1');
SET @genre_id = LAST_INSERT_ID();

INSERT INTO Films_Genres (film_id, genre_id) VALUES(@film_id, @genre_id);

Du côté php pour obtenir un identifiant nouvellement attribué pour un champ auto-incrémenté, utilisez $mysqli->insert_id .

Maintenant, si vous voulez créer un nouveau film et l’assigner à plusieurs genres à la fois, vous pouvez le faire.

INSERT INTO Films (Title) VALUES ('Title2');
SET @film_id = LAST_INSERT_ID();
-- if you get ids of genre from your UI just use them
INSERT INTO Films_Genres (film_id, genre_id) 
SELECT @film_id, id
  FROM Genres
 WHERE id IN (2, 3, 4);

INSERT INTO Films (Title) VALUES ('Title3');
SET @film_id = LAST_INSERT_ID();
-- if you names of genres you can use them too
INSERT INTO Films_Genres (film_id, genre_id) 
SELECT @film_id, id
  FROM Genres
 WHERE Name IN ('Genre2', 'Genre4');

VoiciSQLFiddledemo 

15
peterm

Fondamentalement, vous devez également insérer une ligne dans la table des liens pour "lier" un film et un genre que vous venez d'insérer. Le moteur MySQL ne le fait pas automatiquement pour vous (il ne sait tout simplement pas que ces 2 être en quelque sorte lié) - ceci doit être fait côté application ou manuellement

INSERT INTO Films_Genres (film_id,genre_id) VALUES (1,1)
0
diy

Vous devez remplir vous-même votre table plusieurs à plusieurs, c'est comme cela que fonctionne mysql, il n'y a pas de travail de devin automatique effectué ici malheureusement. 

0
silkfire