【问题标题】:Enforce relationship via a foreign key constraint?通过外键约束强制关系?
【发布时间】:2019-09-29 21:36:42
【问题描述】:

假设我有以下表格:

问题、选择、答案

每个问题都有很多选择(选择有一个question_id 外键。)

Answers 表有两个外键 question_id 和 choice_id,这些约束阻止了引用不存在的 question 或 choice 的答案,但我想阻止 invalid em> 也有选择。

我如何表达一个约束(也许这不是正确的词),它只允许choice_id 是给定question_id 的有效选择的答案?例如,如果我有 2 个问题,每个问题有 2 个选项:

  • 第一季度(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) 这样的答案,因为这不是一个有效的选择问题。

【问题讨论】:

  • 我很难理解选择和答案之间的区别。回答是用户对问题的选择吗?
  • 是的,也许他们可以使用更好的名称,但“答案”是用户提交的内容,“选择”是问题的有效选项(多选题)。有更好的名字的想法吗?
  • 在我看来,选项有两种不同的识别方式,choiceId 在所有问题的所有选项中都是唯一的,考生看到的选项编号为 1所有问题都通过 5。你需要注意不要混淆这两个,否则你永远不会得到正确的外键约束。
  • @WalterMitty 确实!我需要小心这一点。我在几个表上存储了一个“订单”属性,以跟踪它们在每个问题中的索引。

标签: sql postgresql database-design foreign-keys many-to-many


【解决方案1】:

您只需要一个从answer 到choice 的FK constraint - choice 中的行作为回报指向一个 适用的问题。

如果您坚持拥有一个冗余列 answer.question_id(在某些极端情况下这是有意义的)仍然只有一个跨越两列的 multicolumn FK 约束。这需要首先在表choice 上匹配多列UNIQUE(或PK)约束(否则通常也是多余的):

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 或者您可能需要做更多:首先了解在这种情况下外键约束的不同匹配类型:

相关:

【讨论】:

    【解决方案2】:

    为什么你的“答案”表有question_id?

    如果它只有一个choice_id,它将始终引用一个现有的选择。选择本身链接到一个有效的问题,唯一地确定给定答案是针对哪个问题的。

    【讨论】:

    • 那是...一个很好的观点:) 完全避免这个问题,我喜欢它。
    • 您甚至根本不需要“答案”表。只在choices 表中添加一个布尔值“valid_answer”列。仅当大多数问题根本没有答案,但只有少数子集有答案时,才在此处使用关系表。
    • @Obsidian "Answer" 不是关系表。
    • @Obsidian 这里的用例是让多个用户能够提交多个问题的答案,其中“answers”表中的每个响应只有一行。
    • @Dave,我同意,但您仍然不需要专门的“答案”表来做到这一点。准确地说,在这种情况下,这不会给您带来更多问题的标志。特别是,这不会帮助您将内容限制为每个问题最多一个有效答案……
    猜你喜欢
    • 2011-10-29
    • 2011-01-19
    • 2020-03-17
    • 1970-01-01
    • 2013-11-22
    • 2019-03-27
    • 2016-02-18
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多