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?
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
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)
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.