MySQLデータベースに多対多の関係を作成しようとしています。 3つのテーブルがあります:Films
、Genres
およびFilms_Genres
。次のコードを使用して設定します。
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
)
しかし、私がいくつかの値をテーブルに挿入しようとすると:
INSERT INTO Films (Title) VALUES ('$title')
INSERT INTO Genres (Name) VALUES ('$genre')
新しい映画はFilms
テーブルに、新しいジャンルはGenres
テーブルにありますが、Films_Genres
テーブルは更新されません-新しい行はありません(phpMyAdminで確認しています)。
私は何が間違っているのですか?
Films_Genres
テーブルに何かを明示的に挿入するまで、テーブルには何も表示されません。 PKおよびFKによる参照整合性は、テーブルにデータを入力するためのものではありません。
Films_Genres
に新しいレコードを挿入するためのMySqlコードは、新しいジャンルに対応する新しい映画の場合、次のようになります。
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);
自動インクリメントフィールドに新しく割り当てられたIDを取得するには、php側で $mysqli->insert_id
。を使用します
新しい映画を作成して、一度に複数のジャンルに割り当てたい場合は、次のことができます。
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');
これはSQLFiddleデモです
基本的に、リンクテーブルにも行を挿入して、挿入したばかりの映画とジャンルを「リンク」する必要があります。Mysqlエンジンは自動的にそれを行いません(これらの2つのレコードが必要であることを単に認識していません)。何らかの形で関連している)-これはアプリケーション側で、または手動で実行する必要があります
INSERT INTO Films_Genres (film_id,genre_id) VALUES (1,1)
自分で多対多のテーブルに入力する必要があります。これがmysqlの動作方法です。残念ながら、ここでは自動推測作業は実行されません。