sql - 外键引用 PostgreSQL 中的其他外键

标签 sql postgresql database-design foreign-keys

在 PostgreSQL 中我有一个数据库,我打算对它进行如下表声明:

CREATE TABLE canvas_user (
    id INTEGER,
    login_id VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(355) UNIQUE NOT NULL,
    name_given VARCHAR(30),
    name_family VARCHAR(30),
    name_full VARCHAR(50),
    role canvas_role,
    last_login TIMESTAMP,
    PRIMARY KEY (id)
);

CREATE TABLE problem (
    id SERIAL,
    title VARCHAR(50),
    author VARCHAR(50),
    path TEXT,
    compiler VARCHAR(20),
    PRIMARY KEY (id)
);

CREATE TABLE assignment (
    id INTEGER,
    title TEXT NOT NULL,
    points_possible INTEGER NOT NULL,
    problem_id INTEGER,
    PRIMARY KEY (id),
    FOREIGN KEY (problem_id) REFERENCES problem(id)
);

CREATE TABLE submission (
    num SERIAL,
    user_id INTEGER,
    assignment_id INTEGER,
    timestamp TIMESTAMP,
    path TEXT,
    lti_info TEXT[],
    PRIMARY KEY(num, user_id, assignment_id),
    FOREIGN KEY (user_id) REFERENCES canvas_user(id),
    FOREIGN KEY (assignment_id) REFERENCES assignment(id)
);

CREATE TABLE correction (
    num INTEGER,
    user_id INTEGER,
    assignment_id INTEGER,
    timestamp TIMESTAMP,
    path TEXT,
    execution_time interval,
    PRIMARY KEY(num, user_id, assignment_id),
    FOREIGN KEY (num) REFERENCES submission(num),
    FOREIGN KEY (user_id) REFERENCES submission(user_id),
    FOREIGN KEY (assignment_id) REFERENCES submission(assignment_id)
);

一切正常,除了在创建最后一张表时出现以下错误(更正):

ERROR: there is no unique constraint matching given keys for referenced table "submission"

我打算使用更正表对每个提交进行唯一的更正,但提交可以有(或没有)更正。

如何解决这个错误?是设计问题还是表声明错误?

最佳答案

外键约束不关心引用的列是否引用了另一列本身。但引用的列必须是唯一的。这就是错误消息告诉您的内容(非常清楚)。

你缺少的是 foreign key constraint can be based on multiple columns .这应该有效:

FOREIGN KEY (num, user_id, assignment_id) REFERENCES submission

替换:

<strike>FOREIGN KEY (num) REFERENCES submission(num),
FOREIGN KEY (user_id) REFERENCES submission(user_id),
FOREIGN KEY (assignment_id) REFERENCES submission(assignment_id)</strike>

语法的简短形式(REFERENCES submission)是可能的,因为您引用的是默认的主键。

此外,您还可以简化:将 submission.num 设为单列主键,从 correction 并将 fk 约束减少到 (num) - 如 @Tim's answer 中所述.

只要您有多列 fk 约束,请考虑对每个引用列的 NOT NULL 约束(如@joop 所评论)。否则,引用列中的一个或多个 NULL 值允许使用默认的 MATCH SIMPLE 行为来逃避 fk 约束。这可能是有意的,也可能不是有意的,通常不是
或者考虑对多列 fk 约束使用 MATCH FULL 以仅在所有 引用列为 NULL 时才允许。详情:

关于sql - 外键引用 PostgreSQL 中的其他外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25430409/

相关文章:

java - 无法通过android studio连接azure数据库

php - 选择所有项目,按项目使用次数排序

sql - 如何排序和挑选 Rails 中的前几项

mysql - 加入只显示一条记录

database - Azure-DocumentDb : Top1 in Group BY Query

sql - 返回按非唯一 SQL 属性排序前后的 X 个元素

sql - unaccent() 防止在 Postgres 中使用索引

java - 计算每日最低余额

mysql - 在数据库中存储时间表

security - 使用主键/ID 字段作为 URL 中的标识符