外键约束的想法是,如果表 Y 中没有与 X 相关的记录,它会阻止在表 X 中创建记录。在您的情况下, Author 和 Book 具有主键,并且 Book_Author 表将 M:M 关系分解为两个 1:M 关系以 Author 和 Book 为键;在您首先在 Book 中创建记录并在 Author 中创建记录之前,您无法在 Book_Author 中创建记录
您似乎在询问是否可以反过来执行此操作,并将 Book 表和 Author 表键入 Book_Author 表
答案是否定的(嗯,没有什么是不,但这是一个非常非常不应该)
为了接受外键关系,Book_Author 必须有一个主键。你会选择什么作为主键?您可以使用 BookID+AuthorID。您可以有一个单独的递增 int 或一个 guid,但是将这种 PK 放在分解 M:M 关联的表上是“仅仅因为你可以,并不意味着你应该”的列表。
您不能只为主键的一部分建立外键,因此如果 Book 和 Author 将作为 Book_Author 的键,而 Book_Author 将有一个复合 PK,那么其他表(Book、Author)将需要额外的列来覆盖密钥的其他元素;你最终会在 book 表中存储一个作者,在 author 表中存储一本书。那么一本有两位作者的书呢?它需要 Book 表中的两个条目,每个作者一个。我们应该在规范化数据库时主动删除这种软数据重复。这一步是主动去规范化。在 Book_Author 表上放置一个递增的 PK 存在相同的论点;您如何表示一本书有 2 个作者?您的关联表中需要 2 行,它们不能有相同的 PK 值,所以让我们给它们不同的值:
BookAuthorId, Book, Author
1, GoodOmens, NeilGaiman
2, GoodOmens, TerryPratchett
现在我们必须为这些图书创建引用我们在 Book_Author 中的主键列的图书:
Book Name, BookAuthorId, Description
Good Omens, 1, A funny story about life as a fallen angel
Good Omens, 2, A funny story about life as a fallen angel
你花更多的时间去思考“Book_Author 应该是主键,Book 和 Author 表应该是它的外键”这个概念,你就会越多地意识到它绝对不可行并且什么都解决不了,它只会创建头痛
一本书,书表中的一行。一位作者,作者中的一行。我们有这些规则是因为只有一个 Terry Pratchett,一个 Neil Gaiman,一个叫做 Good Omens 的故事。所有这些“一个”东西都应该有一行,一个主键标识它。当我们想将这些东西组合在一起时,我们使用另一个具有复合键的表,以确保我们不能将 Neil Gaiman 记录为两次写好预兆,以及确保我们链接在一起的书和作者确实存在的外键。将书分配给不存在的作者,将不存在的书分配给作者是没有意义的..
所以,这就是为什么这些东西是“那样”圆的; “反过来”没有好处