postgresql 外键语法

Posted

技术标签:

【中文标题】postgresql 外键语法【英文标题】:postgresql foreign key syntax 【发布时间】:2015-04-17 23:55:00 【问题描述】:

我有 2 个表,您将在下面的 posgresql 代码中看到。第一个表学生有 2 列,一个用于 student_name,另一个用于主键 student_id。 在我的第二个名为 tests 的表中,它有 4 列,一列用于 subject_id,一列用于 subject_name,然后一列用于在最高Student_id 的科目中得分最高的学生。我试图让 highstStudent_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);

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

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

【问题讨论】:

是的,语法是“正确的”。然而,FK 列应该定义为serial,它应该定义为integerserial 不是“真实”数据类型,它是从序列中填充默认值的简写 如果 FK 引用主键,则不需要列。如果 FK 引用了备用键,则需要列。 您的外键引用了“玩家”表。您似乎没有名为“players”的表格。 @Mike Sherrill 'Cat Recall 对不起,我的错误是指最高的Student_id 整数参考学生 【参考方案1】:

假设这张表:

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

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

    内联不提目标列:

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

    内联提及目标列:

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

    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)
    );
    

    作为单独的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 中的“约束”命令来完成。另外,将 FOREIGN KEY 放在 FK 之前怎么样?看起来当我们这样做时,我们不必声明变量类型? 对于alter table 变体,如果您不想指定约束名称,顺便说一句。这有效:ALTER TABLE "FROM_TABLE" ADD FOREIGN KEY ("FROM_COLUMN") REFERENCES "TO_TABLE" ("TO_COLUMN");

以上是关于postgresql 外键语法的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 添加各种约束语法

sql [查找表的外键关联]找到一个表的外键postgresql #PostgreSQL

在 Postgresql 中索引外键

Postgresql多个表具有相同的外键唯一约束

PostgreSQL - 如何使用外键聚合数据?

POSTGRESQL外键引用两个不同表的主键