【问题标题】:Which table should be Parent table and which should be child table?哪个表应该是父表,哪个应该是子表?
【发布时间】:2016-05-20 17:35:42
【问题描述】:

您好有两张表 Auther 和 Books。 我很困惑我应该将哪个表作为父表,哪个应该作为子表来进行外键约束。

CREATE TABLE author
 (
    author_id NUMBER(3) CONSTRAINT athr_aid_pk PRIMARY KEY,
    author_name VARCHAR2(30)
 );

 CREATE TABLE books
 (
    book_id NUMBER(3),
    book_title VARCHAR2(30),
    book_price NUMBER(3),

 );

请解释一下哪个表应该是父表,为什么?

【问题讨论】:

    标签: database database-design


    【解决方案1】:

    答案:无。

    原因:这是多对多的关系。一个作者可以写任意数量的书,一本书也可以有多个作者。

    解决办法:单独建一个表,两列author_id,book_id都是外键。

    【讨论】:

    • 如果允许 OP 创建一个新表 +1,这很有意义
    【解决方案2】:

    你已经得到了正确的答案。我想添加技术视图:要添加的列。

    外键约束意味着您在一个表中有一个列或一组列,它们可以唯一地标识另一个表中的一条记录。

    为了在表author 中的一本书上有一个外键,您需要将book_id 添加到该表中。但这没有任何意义。 你会在这个领域参考作者的哪本书?所以books 根本不能是关系的父表。

    然后你可以反之亦然:在表books 中有author_id,这意味着一本书只能由一个作者写。这足以满足您的数据库要包含的内容吗?那么这就是要走的路。

    这些提到的关系是 1:n 关系(一个作者可以写几本书一个书可以由几位作者撰写)。但如前所述,更典型的作者/书籍现实是 n:m(一个作者可以写几本书 一本书可由几位作者撰写)。

    要在数据库中引入 n:m 关系,您需要添加一个包含两个表 ID 的桥接表。而且这个桥接表会用外键引用两个父表。

    【讨论】:

      【解决方案3】:

      您可以将 Author 设为父表,将 Books 设为子表。

      原因:一个作者可以写多本书,但一本书(通常)只能由一个作者写。

      【讨论】:

      • 我同意你的看法。但是多个作者也可以为一本书做出贡献。 @Rahul Tripathi
      • @SubrataDeyPappu:- 是的,这就是我添加usually 的原因。此外,多位作者为一本书做出贡献的机会非常罕见/更少
      • 这是一个有效的解决方案。 (您甚至可以在作者表中添加抽象作者,例如写作二重奏,例如“Kami Garcia & Margaret Stohl”,以便在一本书中涵盖多个作者。只要不这样做就可以了对您而言,那么单个作者与他们在数据库中的合作之间没有任何关系。)
      【解决方案4】:

      我会选择另一种方法,而不是拥有父表和子表。 像这样创建一个额外的表:

      CREATE TABLE authors_books
       (
          author_id NUMBER(3),
          book_id NUMBER(3),
          PRIMARY KEY (`author_id`, `book_id`),
          CONSTRAINT `FK_author_books__author`
              FOREIGN KEY (`author_id`)
              REFERENCES `author` (`author_id`)
              ON DELETE CASCADE
              ON UPDATE CASCADE,
          CONSTRAINT `FK_author_books__book`
              FOREIGN KEY (`book_id`)
              REFERENCES `books` (`book_id`)
              ON DELETE CASCADE
              ON UPDATE CASCADE,
       );
      

      这样您就可以避免作者和书籍之间的 n 到 m 关系出现任何问题。现在一本书也可以由多个作者撰写。

      您可能还想拥有一个额外的字段order,以始终保持唯一的PK。所以PK是PRIMARY KEY (author_id,book_id,order).

      【讨论】:

        【解决方案5】:

        解释1

        如果您考虑作者与书籍之间的一对多关系,那么作者将是父母。实际上作者将是关系的所有者。他会将作者的实际映射到书籍表。

        解释2:

        如果您考虑作者与书籍之间的多对多关系,那么没有人会成为父母。两者具有同等重要性。

        【讨论】:

          【解决方案6】:

          FOREIGN KEY 声明表示出现在表的列出列下的每个值子行 REFERENCES 也出现在被引用表的列出列下。引用的列必须是 UNIQUE NOT NULL 或 PRIMARY KEY。 “父”表是被引用的表。

          只要是这种情况,就声明一个 FOREIGN KEY。否则不要。

          如果您在两个列列表上 JOIN,结果将恰好每个引用表行只有一行。

          对于您的两个表,没有要声明的外键。

          如果您添加一个表 author_books,其中包含“作者 AUTHOR_ID 创作的图书 BOOK_ID”的行,则其 author_id 值必须位于 author 中,其 book_id 值必须位于 books 中。所以声明两个 FOREIGN KEY:

          FOREIGN KEY (author_id) REFERENCES author (author_id)
          FOREIGN KEY (book_id) REFERENCES books (book_id)
          

          (如果作者总是只写一本书,那么您可以将book_id 添加到author,并使用外键添加到books。如果一本书总是只有一个作者,那么您可以将author_id 添加到@987654332 @ 带有来自 author 的外键。但这不是作者和书籍的真实情况。)

          约束声明允许 DBMS 禁止错误的更改,这些更改会使数据库的值不正确。 You don't need constraints to query a database.(包括 UNIQUE NOT NULL、PRIMARY KEY 或 FOREIGN KEY。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-10-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多