【问题标题】:What is difference between foreign key and reference key?外键和引用键有什么区别?
【发布时间】:2012-01-25 14:40:52
【问题描述】:

我对这两个术语感到非常困惑。它们是相同的还是不同的?

有些书和人说他们是一样的,有些人说他们是不同的。

我试过了,但找不到确定的答案。

【问题讨论】:

    标签: sql database foreign-keys


    【解决方案1】:

    我假设您正在谈论使用REFERENCES,其中在约束内联列时不使用FOREIGN KEY 关键字,这称为列级外键约束,例如.

    author_id INTEGER REFERENCES author(id)
    

    ... 而不是 table-level 外键约束,它放在列声明之后...

    author_id INTEGER,
    FOREIGN KEY(author_id) REFERENCES author(id)
    

    答案是,它只是同一事物的简写语法。在两者之间进行更改时的主要关注点应该是可读性。

    对于更高级的使用,可能只有表级外键约束可以同时描述多个键的约束,其中所有键都必须存在于引用的表中。


    请注意 MySQL 'parses but ignores “inline REFERENCES specifications” (as defined in the SQL standard) where references are defined as part of the column specification',这意味着只有表级外键约束才会工作。

    PostgresMicrosoft's SQL Server 都尊重列级和表级外键约束。

    【讨论】:

    • 虽然第一个可以在不启用外键的情况下工作,而第二个则不会。第二种方式就不再使用了吗?
    • 如果您尝试使用逆向工程从 MySQL Workbench 中的数据库创建图表,这也很重要。如果您在创建数据库时使用了第一个选项,该工具将无法在图表元素之间创建连接。
    • 那么,我们应该使用FOREIGN KEY来使用第二个选项吗?
    • 这就是我想要的。这是simply shorthand syntax for the same thing.
    • @exSnake 我终于有时间更新答案,注意到 MySQL 和其他实现之间的区别 :-) 感谢您的提示!
    【解决方案2】:

    外键必须引用主键。 当简单地使用 REFERENCES 约束时,被引用的键不必是主键。

    【讨论】:

    • 我刚刚尝试过这种情况,我想确保列值存在于另一个表中(既不是唯一的也不是 PK)。可悲的是,您的建议不适用于这种情况。引用的列是否仍然必须是唯一的?
    【解决方案3】:

    “引用键”不是关系建模或美国英语 SQL 实现中的普通技术术语。

    外键“引用”其他表中的键;这可能是混乱的来源吗?

    【讨论】:

      【解决方案4】:

      您并没有真正将某事称为 reference key...它们是相同的...您可能会看到例如 sqlite 中使用的单词 references:您可以使用这样的语法来创建作者和书籍的数据库。这使您可以显示一位作者可以拥有多本书。这告诉数据库books.author_id(定义了几行)引用author.id

      CREATE TABLE 'author' (
          id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
          firstname varchar(255)
          lastname varchar(255)
      );
      
      CREATE TABLE 'books' (
          id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
          author_id INTEGER,
          title varchar(255),
          published date,
          FOREIGN KEY(author_id) REFERENCES author(id)
      );
      

      【讨论】:

        【解决方案5】:

        “FOREIGN KEY”和“REFERENCES”这两个关键字唯一和最重要的区别是虽然它们都将数据作为父表的子数据,但“FOREIGN KEY”用于创建表级别约束,而 REFERENCES 关键字只能用于创建列级别约束。列级别约束只能在创建表时创建。但是可以使用 ALTER TABLE 命令添加表级别约束。

        【讨论】:

          【解决方案6】:

          就标准 SQL 而言,两者都会导致外键约束。

          一种形式是一个表格约束,这意味着它可以应用于一个或多个列。您需要它来引用具有多列主键的表:

          CREATE TABLE child (
              id int PRIMARY KEY,
              parent_id int,
              date date,
              FOREIGN KEY (parent_id, date) REFERENCES parent(id, date)
          );
          

          另一种形式是列约束,这意味着它只能应用于定义它的单个列。它不能用于引用具有多列主键的表。

          CREATE TABLE child (
              id int PRIMARY KEY,
              parent_id int REFERENCES parent(id)
          );
          

          上述语法的工作方式与为单个列声明表约束完全相同(假设 RDBMS 支持这种类型的列约束),如下所示:

          CREATE TABLE child (
              id int PRIMARY KEY,
              parent_id int,
              FOREIGN KEY (parent_id) REFERENCES parent(id)
          );
          

          它经常让 MySQL 及其 InnoDB 存储引擎的用户感到困惑,即不支持后一种列约束样式。您必须为外键定义表级约束,即使它是单列约束。这是 MySQL 自早期以来的一种奇怪行为,即某些约束语法是有效的,但不会产生任何约束。请参阅此处的讨论:https://bugs.mysql.com/bug.php?id=17943

          【讨论】:

          • 第二个例子(代码)是申请单列的表约束对吧?还是列约束?
          • 这是一个表约束。但这种区别仅在于它在语法中的出现位置。它们都是外键约束,功能相同。我进行了编辑以澄清,但它改变了示例的顺序,因此您的评论现在指的是第三个示例。
          【解决方案7】:

          也许您使用术语“参考键”有点松散?

          一行中的外键值被称为“引用”包含相应键值的行。注意前面句子中的“reference”这个词是一个动词,所以我们可以说我们有一个引用外键值和一个被引用键值。

          虽然引用的是键值,而不是表键约束,但我想松散地说,我们可以说“引用键”来表示包含可能被引用的值的行。然后我看到“引用的密钥”如何成为“引用的密钥”,但不能掩盖它的起源。

          【讨论】:

            【解决方案8】:

            有两种方法可以声明外键:

            1. 如果外键是 SINGLE 属性:
              参考文献()

            2. 如果外键是属性列表

            外键()引用

            【讨论】:

              【解决方案9】:

              外键“引用”其他表中的键。其他表中的那个键称为引用键。如果您在 phpmyadmin 上使用图形功能,您可能会听到很多关于此的信息。

              【讨论】:

                【解决方案10】:

                引用键是另一个表中引用的主键。 另一方面,外键是您将第二个表链接到主表主键(或引用键)的方式。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-01-24
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-09-30
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多