两个表,每个表都有一个外键引用另一个表。

7

我正在尝试创建一个数据库以存储一些问题和答案,用于一项小测验。

到目前为止,我有两个表:

questions:(问题ID(PK),问题字符串,正确答案ID)

answers:(答案ID(PK),答案字符串,问题ID)

我在设置外键约束时遇到了麻烦。肯定需要确保 correct answer ID存在于 answers 中,并且还要确保 answers 中的 question ID 存在于 questions 表格中。但是,尝试在SQliteStudio中添加这些外键时,我得到了错误消息,表明当已经存在从B > A的外键约束时,无法添加一个从表A > B的外键约束。

4个回答

5

这是正确的行为。否则,你会遇到鸡生蛋的问题:你不能在插入问题行之前插入答案行,也不能在插入有效的答案行之前插入问题行。尝试删除引用的问题或答案时,也会遇到类似的问题。

解决这个问题的典型方法是在answer表中添加一个is_correct列。


1
我确实考虑过鸡和蛋的情况,但是我假设您可以只添加外键字段中具有“null”值的行,并在添加所有行后更新它们。不过,我想这会让您面临其他潜在问题。感谢您的建议。 - Roger Jarvis
我也喜欢你提出的解决方案,因为它允许一个问题有多个正确答案的可能性。 - Roger Jarvis

0

http://www.sqlite.org/foreignkeys.html#fk_schemacommands

当启用外键约束时,ALTER TABLE命令在两个方面的工作方式不同:
无法使用“ALTER TABLE…ADD COLUMN”语法添加包含REFERENCES子句的列,除非新列的默认值为NULL。尝试这样做会返回错误。
...
ALTER TABLE和DROP TABLE命令的这些改进的目的是确保它们在启用外键约束时不能用于创建包含外键违规的数据库。

0
我认为这种情况可以用关系表建模:
QA: (问题ID(FK),答案ID(FK),正确,...),其中2个FK代表表的PK。

0
针对你的问题,无论外键列是否可为空,在两个表之间建立相互引用的外键约束时,只要表是空的,就不会出现问题。
但是,当这两个表都有数据时,我们必须考虑到主键数据和外键列的可为空类型。例如,表 Question:
QuestionID Question AnswerID 1 'Question1' 1 2 'Question2' 2
AnswerID Answer QuestionID 3 'Answer1' 3 4 'Answer2' 4
现在,如果你尝试设置外键约束,则会失败,因为它们已经违反了外键规则。
简单来说,只有当当前数据不违反外键约束时,你才能设置外键约束。
  1. 如果在您的情况下,外键列不允许为空,在设置了外键约束后,您仅限于第三列(QuestionID或AnswerID)中的当前数据

  2. 即使您能够使用NULL实现它,同样适用于删除操作。 您必须跟踪两个表:在引用表中将相应列设置为null 删除表将不起作用

更好的方法: 这些QuestionID、AnswerID应该映射到另一个表SchemaName.[Mapping] 根据您的逻辑确定正确的答案ID。考虑是否支持N*N映射。

不要在内部链接两个表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接