PostgreSQL Составной внешний ключ 'список столбцов не должен содержать дубликатов' - PullRequest
0 голосов
/ 09 июля 2020

Это моя схема примера:

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 ]

2 голосов
/ 09 июля 2020

Вам нужны два отдельных ограничения внешнего ключа:

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 голос
/ 09 июля 2020

Хотя я предпочитаю синтаксис, показанный Гордоном, если вам нужен одинарный лайнер, вы можете сжать его как:

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

... только для получения идентификаторов fk1 и fk2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...