【问题标题】:Can/how do you add a circle of references without breaking RI?您可以/如何在不破坏 RI 的情况下添加参考圈?
【发布时间】:2010-09-15 19:51:16
【问题描述】:

我主要对 pgsql 感兴趣,但我想知道是否有任何 RDBMS 中的方法可以进行插入操作,无需禁用和重新启用任何 FOREIGN KEY 或 NOT NULL约束,在两个相互引用的表上。 (你可能会认为这是一只从自己的蛋中诞生的鸡。)

举个实际的例子,如果你有一个选择题测验系统,有表格“question”和“answer”,其中 question.correct_answer 指 answer.id, answer.question 指 question.id,是吗?可以同时添加问题及其答案吗?

(作为记录,我知道您可以在事务块中执行禁用和重新启用,并且另一种解决方案是没有正确答案列,而是将 answer.correct 作为布尔值并有检查约束以确保每个问题都有一个正确答案。但我对这里的替代解决方案并不好奇。)

【问题讨论】:

  • 这个问题的标题很差。尝试使其适合实际问题。
  • 感谢您的建议。希望新标题更有帮助。

标签: sql postgresql foreign-keys


【解决方案1】:

我认为您已经回答了自己的问题 - 您必须创建一个交易块。在 PostgreSQL 中这应该可以工作:

BEGIN;
  SET CONSTRAINTS ALL DEFERRED;
INSERT INTO questions (questionid, answerid, question)
  VALUES (1, 100, 'How long are Abraham Lincoln\'s legs?');
INSERT INTO answers (answerid, questionid, answer)
  VALUES (100, 1, 'Long enough to reach the ground.');
COMMIT;

它必须在事务块中,因为如果任一 INSERT 语句失败,数据库将处于无效状态(未满足表约束)。

【讨论】:

  • PostgreSQL 中 SET CONSTRAINTS 的一个问题是它只延迟外键约束。例如,您不能使用它来推迟 NOT NULL 约束。但在实践中,外键约束是最常见的。
【解决方案2】:

我会这样做:

  1. 将 Questions.correct_answer 定义为 可为空的列。
  2. 在 Questions 中插入行,将 correct_answer 设置为 NULL。
  3. 在 Answers 中插入行,引用 Questions 中的行。
  4. 更新问题 SET correct_answer = ?

【讨论】:

  • 感谢您的回答,但我的意思是它必须使 NOT NULL 约束完好无损。
  • 好吧,很公平,那么 Neall 的回答更好,将约束执行推迟到事务结束。
【解决方案3】:

在一个问题和一个答案的简单情况下,建议将所有属性放在一个表中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-19
    • 2011-11-26
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多