Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL many-to-many relationship with FOREIGN KEYS

I am trying to create a many-to-many relationship in my MySQL database. I have three tables: Films, Genres and Films_Genres. I am using the following code to set them up:

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
)  

However, when I try to insert some values into the tables with:

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

I can see the new Film in Films table and the new Genre in Genres table but the Films_Genres table doesn't update - there are no new rows (I'm checking through phpMyAdmin).

What am I doing wrong?

like image 963
Sharkz Avatar asked Jul 03 '13 23:07

Sharkz


People also ask

Does a many-to-many relationship have a foreign key?

In a many-to-many relationship, a row in table A can have many matching rows in table B, and vice versa. You create such a relationship by defining a third table that is called a junction table. The primary key of the junction table consists of the foreign keys from both table A and table B.

How do I create a many-to-many relationship in mysql?

When you need to establish a many-to-many relationship between two or more tables, the simplest way is to use a Junction Table. A Junction table in a database, also referred to as a Bridge table or Associative Table, bridges the tables together by referencing the primary keys of each data table.

How do you implement many-to-many relationships?

To create many-to-many relationships, you need to create a new table to connect the other two. This new table is called an intermediate table (or sometimes a linking or junction table).

Can you relate data to multiple tables using a foreign key?

A Foreign Key is a database key that is used to link two tables together. The FOREIGN KEY constraint identifies the relationships between the database tables by referencing a column, or set of columns, in the Child table that contains the foreign key, to the PRIMARY KEY column or set of columns, in the Parent table.


Video Answer


1 Answers

You won't see anything in Films_Genres table until you explicitly insert something in it. Referential integrity through PK and FK is not for populating your tables for you.

Your MySql code for inserting a new record in Films_Genres, if it's a new film which correspond to a new genre, might look like

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);

On php side to get a newly assigned id for an autoincremented field use $mysqli->insert_id.

Now if you want to create a new film and assign it to multiple genres at once you can do

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');

Here is SQLFiddle demo

like image 74
peterm Avatar answered Sep 21 '22 09:09

peterm