PostgreSQL复合外键“列列表不得包含重复项”

时间:2020-07-09 12:34:28

标签: sql postgresql

这是我的示例架构:

CREATE TABLE users (
    userid BIGSERIAL PRIMARY KEY,
    name varchar(25) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE follows (
    userid1 int NOT NULL,
    userid2 int NOT NULL,
    PRIMARY KEY (userid1, userid2),
    FOREIGN KEY (userid1, userid2) REFERENCES users (userid) ON DELETE CASCADE
);

如果运行此命令,则会得到:

ERROR: number of referencing and referenced columns for foreign key disagree

如果我添加... REFERENCES users (userid, userid) ON DELETE CASCADE

我得到:

ERROR: foreign key referenced-columns list must not contain duplicate

我知道,如果我在每一行中键入他们各自的引用,这是可行的,但是最好不要重复自己。

如何使用具有相同依赖性的复合外键来实现这一目标?

2 个答案:

答案 0 :(得分:2)

您需要两个单独的外键约束:

CREATE TABLE follows (
    userid1 int NOT NULL,
    userid2 int NOT NULL,
    PRIMARY KEY (userid1, userid2),
    FOREIGN KEY (userid1) REFERENCES users (userid) ON DELETE CASCADE,
    FOREIGN KEY (userid2) REFERENCES users (userid) ON DELETE CASCADE
);

答案 1 :(得分:1)

尽管我更喜欢Gordon显示的语法,但是如果您想要一个衬板,可以将其压缩为:

CREATE TABLE follows (
    userid1 int NOT NULL REFERENCES users ON DELETE CASCADE,
    userid2 int NOT NULL REFERENCES users ON DELETE CASCADE,
    PRIMARY KEY (userid1, userid2)
);

这种简写形式的缺点是FK没有名称。如果您需要删除或修改它们,将来管理它们可能会很棘手。经验告诉我,最好给它们命名,并且您需要使用完整的语法,如:

CREATE TABLE follows (
    userid1 int NOT NULL,
    userid2 int NOT NULL,
    PRIMARY KEY (userid1, userid2),
    CONSTRAINT fk1 FOREIGN KEY (userid1) 
      REFERENCES users (userid) ON DELETE CASCADE,
    CONSTRAINT fk2 FOREIGN KEY (userid2) 
      REFERENCES users (userid) ON DELETE CASCADE
);

...只是为了获得fk1fk2标识符。