Обеспечить связь через ограничение внешнего ключа? - PullRequest
2 голосов
/ 13 мая 2019

Допустим, у меня есть следующие таблицы:

Вопросы, варианты, ответы

Каждый вопрос имеет много вариантов (варианты имеют question_id внешний ключ.)

Таблица ответов содержит два внешних ключа, question_id и choice_id, и эти ограничения запрещают ответы, которые относятся к несуществующим question или choice, но я хочу предотвратить неверный выбор,тоже.

Как я могу выразить ограничение (может быть, это не то слово), которое разрешает ответы только в тех случаях, когда choice_id является допустимым выбором для данного question_id?Например, если у меня было 2 вопроса, каждый с 2 ​​вариантами ответа:

  • Q1 (id = 1)
    • A (id = 1)
    • B (id= 2)
  • Q2 (id = 2)
    • C (id = 3)
    • D (id = 4)

Я хочу разрешить ответы типа (question_id = 1, choice_id = 1 (или 2)) и запретить ответы типа (question_id = 1, choice_id = 4)потому что это неправильный выбор для вопроса.

Ответы [ 2 ]

6 голосов
/ 13 мая 2019

Все, что вам нужно, это ограничение FK от answer до choice - строка в choice указывает на один применимый вопрос в ответ.

Если вы настаиваете на избыточном столбце answer.question_id (в некоторых случаях это имеет смысл), все равно есть только одно ограничение multicolumn FK, охватывающее оба столбца.Для этого необходимо сначала сопоставить многостолбцовое ограничение UNIQUE (или PK) для таблицы choice (в других случаях также обычно избыточно):

ALTER TABLE choice ADD CONSTRAINT choice_uni UNIQUE (question_id, choice_id);

Затем:

ALTER TABLE answer ADD constraint answer_choice_fkey
FOREIGN KEY (question_id, choice_id)  REFERENCES choice(question_id, choice_id);

Все задействованные столбцыNOT NULL или вам, возможно, придется сделать больше: начните с изучения различных типов соответствия ограничений внешнего ключа в этом случае:

Похожие:

3 голосов
/ 13 мая 2019

Почему в вашей таблице "ответов" есть question_id?

Если он имеет только choice_id, он всегда будет ссылаться на существующий выбор. Сам выбор связывается с действительным вопросом, однозначно определяя, на какой вопрос дан данный ответ.

...