postgresql外键语法

Ham*_*mza 111 sql postgresql foreign-keys foreign-key-relationship relational-database

我将在下面的posgresql代码中看到2个表.第一个表学生有2列,一个用于student_name,另一个student_id是主键.在我的第二个名为tests的表中,它有4列,一个用于subject_id,一个用于subject_name,然后一个用于在一个主题中具有最高分数的学生,即最高学生.我试图让highStudent_id在我的学生表中引用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);
Run Code Online (Sandbox Code Playgroud)

语法highestStudent_id SERIAL REFERENCES students是否正确?因为我见过另一个喜欢的人highestStudent_id REFERENCES students(student_id))

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

a_h*_*ame 214

假设这个表:

CREATE TABLE students 
( 
  student_id SERIAL PRIMARY KEY,
  player_name TEXT
);
Run Code Online (Sandbox Code Playgroud)

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

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

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

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
    
    Run Code Online (Sandbox Code Playgroud)
  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)
    );
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    
    Run Code Online (Sandbox Code Playgroud)

你喜欢哪一个是品味问题.但是你的脚本应该是一致的.如果您的外键引用包含多个列的PK,则最后两个语句是唯一的选项 - 在这种情况下,您无法定义FK"内联",例如foreign key (a,b) references foo (x,y)

只有版本3)和4)才能让你能够为FK约束定义你自己的名字,如果你不喜欢Postgres的系统生成的那个.


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

  • 对于“alter table”变体,如果您不想,则无需指定约束名称,顺便说一句。这有效:`ALTER TABLE“FROM_TABLE”添加外键(“FROM_COLUMN”)引用“TO_TABLE”(“TO_COLUMN”);` (3认同)
  • @Venryx 指定约束名称总是一个好主意。当您必须通过迁移消除这些限制时,事情就会变得更容易。如果没有名称,这将是一场噩梦,因为每个服务器都会生成自己的名称,并且您的迁移脚本可能会失败。 (3认同)

小智 5

ALTER TABLE table_name ADD FOREIGN KEY(colunm_name) REFERENCES reference_table_name(reference_column_name);
Run Code Online (Sandbox Code Playgroud)

请注意,该列必须已创建。