简体   繁体   中英

Create a one to many relationship in MySQL

I have two tables, one with arbitrary rows of books and one with specific rows of subjects and ids.

mysql> describe books;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  |     | NULL    |       |
| title | varchar(250) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+


mysql> describe subjects;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id       | int(11)      | YES  |     | NULL    |       |
| subjects | varchar(250) | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+

I want to associate one book to many subject ids, is there any array type I can use so that one column in my books table contains an array of different subject ids?

Can I then do a query on the books table to see which books are related to one subject?

This is a many-to-many relationship, not a one-to-many relationship. (A book can have several subjects, and a subject can have several books.)

The normative pattern is to implement a third table to store the "relationship" between books and subjects.

As an example of a minimal relationship table:

CREATE TABLE books_subjects
( subjects_id  INT(11) NOT NULL COMMENT 'PK, FK ref subjects(id)'
, books_id     INT(11) NOT NULL COMMENT 'PK, FK ref books(id)'
, PRIMARY KEY (subjects_id, books_id)
);

For InnoDB, we can define the foreign key constraints:

ALTER TABLE books_subjects ADD CONSTRAINT FK_books_subjects_books
  FOREIGN KEY (books_id) REFERENCES books(id);

ALTER TABLE books_subjects ADD CONSTRAINT FK_books_subjects_subjects
  FOREIGN KEY (subjects_id) REFERENCES subjects(id);

This effectively resolves the many-to-many relationship into two one-to-many relationships.

A books can have multiple books_subjects , but a books_subjects is related to exactly one books .

A subjects can have multiple books_subjects , but a books_subjects is related to exactly one subjects .


Queries to retrieve books related to a particular subjects would involve a JOIN operation to the books_subjects table.

For example, to find all books of particular subjects :

SELECT b.id
     , b.title
  FROM books b
  JOIN books_subjects j
    ON j.books_id = b.id
  JOIN subjects s
    ON s.id = j.subjects_id
 WHERE s.subjects = 'Psychology'
 ORDER BY b.title

To find books that don't have any subjects , eg

SELECT b.id
     , b.title
  FROM books b
  LEFT
  JOIN books_subjects j
    ON j.books_id = b.id
 WHERE j.books_id IS NULL
 ORDER BY b.title

NOTE: I typically use singular names for tables. So, there would be a lot fewer "s" characters in my column names and foreign key names. I may have omitted an "s" or two in my typing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM