如何在 SQL 中的 3 table(2 对 1)之间建立关系 table

how to make a relationship table between 3 table (2 to 1) in SQL


假设我们的数据库中有 3 table


tables:

table books:
book_id
book_title
...


table magazines:
magazine_id
magazine_title
...


and genres:
genre_id:
genre_name

现在我们说想知道什么书有什么类型什么杂志有什么类型,这是我知道的两个方式table


关系tables:

table book_genres:
genre_id
book_id


table magazine_genre:
genre_id
magazine_id

在这种情况下,我们必须创建几个单独的 table 来加入书籍、杂志和更多 table。我被告知在 join tables.

中总是有 2 个 id 列

但我想知道我是否可以做这样的事情


那个table不行!

table title_genres:
genre_id
book_id
magazine_id
...

这更简单,但是当我插入一本书类型时出现错误,说 magazine_id 不能为空 NULL 因为它的主键。 它将节省我创建大量 table 的时间。就像如果我决定有一个类别 table 那么我必须分别加入书籍和杂志。 我的问题是:2 列是一个好的做法还是有更好的方法?

如果您有一个包含信息(书籍、杂志等)的类别字段,您完全可以用这种方式存储记录。因此,换句话说,您的 table 按类别字段垂直分区,但逻辑上它是单个 table.

我能看到的唯一缺点是,如果这个 table 增长很快,那么查询性能就会成为一个问题,因为 (a) table 会很大,所以它会消耗更多的内存,即使你是仅查找特定类别而不是所有类别(b)您始终必须使用内联子查询,因为每次连接都必须应用类别过滤器,并且当您使用内联查询进行连接时,数据库将无法使用索引的数量将影响查询的性能。

注意:您无法以任何其他方式存储记录。例如,即使一本杂志和一本书的类型相同,您也必须将它们放在不同的行而不是同一行,因为如果这样做,您的模型会遇到其他类型的麻烦。

您使用桥梁 table 来表示 m:n 关系。如果一本书可以有多种流派,而一本杂志可以有多种流派,那么您需要 table 桥梁,例如您正在展示的 book_genres table。

如果您的数据库中的书籍与杂志有很大不同,那么是的,书籍和杂志有单独的 table。

这导致了两个桥 table,正如您所描述的,我认为这没有任何问题。

你的想法有一座桥table一般来说是可行的,但不能解决任何问题。

不过,让我们看看如何构建这样一个多桥 table。首先,您需要一个检查约束,以确保始终恰好填充 book_idmagazine_id 列之一。那么你想要对 COALESCE(book_id, magazine_id), genre_id 的唯一约束。这通常使用函数索引来完成,据我所知 MySQL 不支持。不过,我想您可以创建一个生成的列,您可以在 MySQL.

中建立索引

然后您想尽快阅读关系。使用像 book_genres 这样的桥 table ,每本书和流派都有一行,还有一个索引可以尽快获得关系。使用像 title_genres 这样的多桥 table 你不需要。您有一个 table 包含您感兴趣的关系和其他您不感兴趣的关系。您需要一个部分索引,如

create unique index idx on title_genres (book_id, genre_id) where book_id is not null;

但 MySQL 不支持部分索引。你可以

create unique index idx on title_genres (book_id, genre_id);

这会导致更大的索引,但达到了目的。你会对

做同样的事情
create unique index idx2 on title_genres (magazine_id, genre_id);

现在,通过所有这些工作,您获得了什么?您的数据库已经变得比简单的 book_genresmagazine_genres table 复杂得多。把事情简单化。使用这两个 table 代替多桥怪物 :-)