Postgres ( Постгрес ):Уникальная ссылка от A до B
-
18-09-2019 - |
Вопрос
Я хочу биекцию между парой (tag1, tag2) и tag_id .
CREATE TABLE tags (
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
PRIMARY KEY(question_id, tag_id),
(tag1, tag2) UNIQUE references tags(tag_id) #How?
);
Мне не нужны такие ссылки, как:
(PHP, Perl) points to 1 and 2,
3 points to (C#, null) and (Python, Elinks)
Другими словами, я хочу, чтобы ССЫЛКА была уникальной ОТ (tag1, tag2) До тегов(tag_id), а не УНИКАЛЬНОЙ (tag1, tag2).
Решение
Это может быть больше похоже на то, что вы ищете:
CREATE TABLE tags (
question_id INTEGER NOT NULL,
tag_id SERIAL NOT NULL,
tag1 VARCHAR(20),
tag2 VARCHAR(20),
PRIMARY KEY (tag_id),
INDEX (question_id),
UNIQUE (tag1, tag2)
);
Использование 'tag_id' в качестве первичного ключа означает, что у вас может быть только одна запись с заданным 'tag_id', и что поиск на основе 'tag_id' будет быстрым.
Индекс по 'question_id' улучшит скорость поиска на основе 'question_id', что, я думаю, вы пытались сделать с вашим исходным определением ПЕРВИЧНОГО КЛЮЧА.Если вы действительно хотите, чтобы пара (tag_id, question_id) была уникальной, как у вас было, тогда добавьте туда УНИКАЛЬНЫЙ (tag_id, question_id), но я бы сказал, что вы должны оставить tag_id в качестве первичного ключа.
Ограничение уникальности для (tag1, tag2) предотвращает наличие дубликатов при обратном отображении.
Вот несколько примеров того, что может сработать:
Работает:
1 -> (x, y)
2 -> (x, z)
Сбой (tag_id является первичным ключом и, следовательно, уникален):
1 -> (x, y)
1 -> (y, x)
Сбой (пара (tag1, tag2) не уникальна):
1 -> (x, y)
2 -> (x, y)
Однако пара (x, y) не равна паре (y, x).Я не уверен, как уловить это ограничение уникальности.