首页 文章

是否应该有一个外键“关联”一个关联实体,或“来自”关联实体?

提问于
浏览
0

我正在尝试为书店 Build 一个数据库 . 以下是整体设计的较小子集 .

目前,我有一个Book实体,其ISBN(主键), Headers 和其他一些属性作为属性 .

我有一个带有author_id(主键)的作者实体,名称 .

由于书和作者是多对多的关系 . 我有一个带有ISBN和author_id作为属性的Authorted_title关联实体 . 因此,ISBN是Book实体的外键,author_id是Author实体的外键 .

我的问题是,是否可以将作为外键的Book实体的ISBN和作者实体的author_id作为外来的关联实体Authored_title中的相应属性而不是相反(与我在前一段中提到的相反)?

在考虑之后我有点困惑 . 在谈到FK时, table 之间甚至还有“来”和“来自”的东西吗?

2 回答

  • 1

    不 . 您的初始实施是正确的 . 链接表中的FK引用实体表中的PK .

    Edit

    由于外键需要引用主键,因此无法添加引用链接表的外键 . 您需要链接表上的两列都是主键,显然这是不可能的 .

    FK -> PK 关系基本上是 many -> one . 在您的情况下,链接表上的许多行将引用实体表上的单个行 .

  • 0

    外键约束的想法是,如果表Y中没有与X相关的记录,它会阻止在表X中创建记录 . 在您的情况下,作者和书籍具有主键和Book_Author表,将M:M关系分解为两个1:M关系键入作者和书籍;在Book中首次创建记录并在作者中创建记录之前,您无法在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表应该是外键的关键”,你就越会意识到它绝对不可行并且什么都不解决,它只会让你头疼

    一本书,书表中的一行 . 一位作者,一位作者 . 我们有这些规则,因为只有一个Terry Pratchett,一个Neil Gaiman,一个名为Good Omens的故事 . 所有这些“一个”东西应该有一行,一个主键标识它......当我们想要将这些东西组合在一起时,我们使用另一个具有复合键的表,确保我们不能将Neil Gaiman记录两次写好Good Omens,以及确保我们连接在一起的书和作者确实存在的外键确实存在 . 没有必要将书分配给不存在的作者,并且不存在书籍给作者 .

    所以,这就是为什么这些东西是“那样”的; “其他方式”没有任何好处

相关问题