PostgreSQL外键语法


122

我有2个表格,您将在下面的posgresql代码中看到。第一个表格的student有两列,一列为student_name,另一列为student_id,这是主键。在我称为测试的第二张表中,该表有4列,一列用于subject_id,一列用于subject_name,然后一列用于在该学科中具有最高分数的学生,该分数最高。我正在尝试使highestStudent_id引用我的students表中的student_id。这是我下面的代码,不确定语法是否正确:

CREATE TABLE students ( student_id SERIAL PRIMARY KEY,
                 player_name TEXT);

CREATE TABLE tests ( subject_id SERIAL,
                   subject_name,
                   highestStudent_id SERIAL REFERENCES students);

语法highestStudent_id SERIAL REFERENCES students正确吗?因为我看过另一个像highestStudent_id REFERENCES students(student_id))

请问在postgresql中创建外键的正确方法是什么?


4
是的,语法是“正确的”。然而,FK列应作为界定serial它应该定义为integerserial不是“真实”数据类型,而是填充序列中默认值的
捷径

如果FK引用主键,则不需要任何列。如果FK引用备用键,则需要列。
jarlh 2015年

1
您的外键引用表“ players”。您似乎没有名为“ players”的表。
Mike Sherrill'Cat Recall'15

@Mike Sherrill'Cat记得很抱歉,我的错是我的意思是SupremeStudent_id整数参考学生
Hamza

Answers:


249

假设此表:

CREATE TABLE students 
( 
  student_id SERIAL PRIMARY KEY,
  player_name TEXT
);

定义外键有四种不同的方法(当处理单个列PK时),它们都导致相同的外键约束:

  1. 内联而不提及目标列:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. 内联提及目标列:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. 里面的线不对create table

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer, 
      constraint fk_tests_students
         foreign key (highestStudent_id) 
         REFERENCES students (student_id)
    );
  4. 作为单独的alter table声明:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer
    );
    
    alter table tests 
        add constraint fk_tests_students
        foreign key (highestStudent_id) 
        REFERENCES students (student_id);

您更喜欢哪一个取决于口味。但是您应该在脚本中保持一致。如果您有外键引用由一个以上的列组成的PK,则最后两个语句是唯一的选择-在这种情况下,您无法定义FK“内联”foreign key (a,b) references foo (x,y)

如果您不喜欢Postgres系统生成的名称,则只有版本3)和4)才可以为FK约束定义自己的名称。


serial数据类型是不是一个真正的数据类型。这只是一种简写形式,它定义了从序列中获取的列的默认值。因此,任何列引用规定为柱serial必须使用适当的碱类型定义integer(或bigint对于bigserial列)


该链接(postgresqltutorial.com/postgresql-foreign-key)显示了另一种方法,该方法只能通过3和4中的“ constraint”命令来完成。此外,将FOREIGN KEY放在FK前面怎么办?看起来当我们这样做时,我们不必声明变量类型吗?
wordsforthewise
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.