【问题标题】:Does using REFERENCES without FOREIGN KEY still create a foreign key?使用没有 FOREIGN KEY 的 REFERENCES 是否仍会创建外键?
【发布时间】:2020-04-08 17:30:25
【问题描述】:

我之前做过一些 SQL,但没有加载。如果您在创建表时使用它而不使用 FOREIGN KEY,我对 REFERENCES 的作用感到有些困惑,例如

author_id INTEGER REFERENCES users(id),

相对于...

FOREIGN KEY (author_id) REFERENCES users(id)

如果这些不同,有什么区别?如果它们相同,应该首选哪种形式?

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    第一个:

    author_id INTEGER REFERENCES users,
    

    ...是以下的简写:

    author_id INTEGER REFERENCES users (id),
    

    ...这是以下的简写:

    FOREIGN KEY (author_id) REFERENCES users (id)
    

    ...这又是 SQL 标准的简写:

    CONSTRAINT <constraint-name> 
    FOREIGN KEY (<column>) 
    REFERENCES <table>(<columns>)
    

    第一个涵盖了基本的、最常见的情况,并且很简洁。很好。

    现在,完整的语法涵盖了所有可能变化的一般情况。例如:

    • 复合外键

      book_id int not null,
      chapter_id int not null,
      constraint fk1 foreign key (book_id, chapter_id) 
        references chapter (book_id, chapter_id)
      

      由于是复合键,所以不能在列级指定,只能在表级指定。

    • 分叉外键

      owner_id int not null,
      constraint fk2 foreign key (owner_id) references person (id),
      constraint fk3 foreign key (owner_id) references company (id)
      

      在这种情况下,同一列指向多个表。想象一下这个结合了复合外键......

    一般来说,您会偶尔看到复合键,而很少会分叉外键。大多数情况下,您会看到简单的外键,这就是速记语法如此有用的原因。

    【讨论】:

    • 我不确定所有这些陈述都是等价的。我相信在没有FOREIGN KEY 的情况下使用REFERENCES 指定了一个列级外键,其操作与外键的流行定义相反,即“表中引用另一个表的主键的一组属性”(维基百科)。在您的第一个示例中,DBMS 假定您要引用 users 的主键。在第二个示例中,您可以引用users 中的任何属性。在第三个示例中,您必须引用users 的主键。
    • @NolanStrait 你是对的。按照答案的特定顺序,概括是正确的。专业化不会。我刚刚阅读了 Wikipedia 文章,它旨在简化。这篇文章将外键描述为一组属性,但它实际上是存在两个表之间的约束,并且对两个表(不仅仅是一个)施加了限制。
    【解决方案2】:

    如果你只使用 REFERENCES PostgreSQL 会创建一个外键:

    postgres=# create table parent(id int primary key);
    CREATE TABLE
    
    postgres=# create table child(id int primary key, fk int references parent);
    CREATE TABLE
    
    postgres=# \d child;
                   Table "public.child"
     Column |  Type   | Collation | Nullable | Default 
    --------+---------+-----------+----------+---------
     id     | integer |           | not null | 
     fk     | integer |           |          | 
    Indexes:
        "child_pkey" PRIMARY KEY, btree (id)
    Foreign-key constraints:
        "child_fk_fkey" FOREIGN KEY (fk) REFERENCES parent(id)
    
    postgres=# 
    

    从语法的角度来看,REFERENCES 用于列级别,而 FOREIGN KEY 用于表级别。

    What is difference between foreign key and reference key?

    【讨论】:

      猜你喜欢
      • 2013-02-06
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      相关资源
      最近更新 更多