繁体   English   中英

在MySQL中建立一对多关系

[英]Create a one to many relationship in MySQL

我有两张桌子,一张桌子有任意行的书,另一张桌子有特定行的主题和ID。

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    |       |
+----------+--------------+------+-----+---------+-------+

我想将一本书与许多主题ID相关联,是否可以使用任何数组类型,以便我的Books表中的一列包含一组不同的主题ID?

然后,我可以在“图书”表上进行查询以查看哪些图书与一个主题相关吗?

这是多对多的关系,而不是一对多的关系。 (一本书可以包含多个主题,而一个主题可以包含多个书籍。)

规范模式是实现第三个表来存储书籍和主题之间的“关系”。

作为最小关系表的示例:

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

对于InnoDB,我们可以定义外键约束:

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

这有效地将多对多关系分解为两个一对多关系。

books可以有多个books_subjects ,但是books_subjects与一books完全相关。

一个subjects可以有多个books_subjects ,但是一个books_subjects恰好与一个subjects


检索与特定subjects相关的books查询将涉及到books_subjects表的JOIN操作。

例如,要查找所有特定subjects books

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

查找没有任何subjects books ,例如

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

注意:我通常对表使用单数名称。 因此,列名和外键名中的“ s”字符会少很多。 我在键入时可能省略了一个或两个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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