我正在尝试为书店建立数据库。以下是整体设计的一小部分。
目前,我有一个Book实体,具有ISBN(主键),书名和其他一些属性。
我有一个作者实体,名称为author_id(主键)。
由于书与作者是多对多的关系。我有以ISBN和author_id为属性的Authorted_title关联实体。因此,ISBN是Book实体的外键,author_id是Author实体的外键。
我的问题是,相对于相反的方式,是否有可能将Book实体的ISBN作为外键指向ISBN,将Author实体的author_id作为外键指向关联实体Authored_title中的各个属性(与我之前提到的相反)段落)?
考虑之后我有点困惑。关于FK,表之间甚至有“到”和“从”这种东西吗?
答案 0 :(得分:1)
外键约束的想法是,如果表Y中没有与X相关的记录,则它可以防止在表X中创建记录。在您的情况下,“作者”和“书”具有主键,将M:M关系分解为两个1:M关系的Book_Author表被键到“作者”和“书”;您必须先在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表中将需要两个条目,每个作者一个。.我们应该在规范化数据库时积极删除这种重复的数据。此步骤正在积极地反规范化。存在用于在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表应该是它的外键”,您越会意识到它绝对是行不通的,什么也解决不了,它只是在创建头痛
一本书,书表中的一行。一位作者,作者中的一行。我们之所以有这些规则,是因为只有一个特里·普拉切特,一个尼尔·盖曼,一个叫好兆头的故事。所有这些“一个”事物都应该有一行,用主键标识它。.当我们要将这些事物组合在一起时,我们使用另一个表,该表具有一个组合键,以确保我们不能两次记录Neil Gaiman。已经写了《好兆头》,以及确保我们确实链接在一起的《 Book》和《 Author》的外键确实存在。没有必要将书籍分配给不存在的作者,将不存在的书籍分配给作者。
因此,这就是为什么这些东西都是“那样”的原因。 “其他方式”没有好处
答案 1 :(得分:0)
不。您最初的实现是正确的。链接表中的FK引用了实体表中的PK。
修改
无法添加引用链接表的外键,因为外键需要引用主键。您需要链接表上的两列都为主键,显然这是不可能的。
FK -> PK
关系本质上是many -> one
。在您的情况下,链接表上的许多行将引用实体表上的一行。