您误用了“功能依赖”。这适用于一个表中的列集。您的意思是问题的正确答案是问题的函数。
情况确实只是“喜欢”“递归”。 FK 表引用中有一个循环。但这并没有定义 FK 之间的相互关系,因此没有递归。我们可以说这两个表是相互约束或同时约束的。或者更清楚的是,某些约束约束了两个表。 (可以表示为两个 FK 约束的合取。)
您的情况可以通过表格和简单的行成员资格条件来描述,如下所示:
Question(qid,text) -- question [qid] has text [text]
key qid
Answer(aid,text) -- answer [aid] has text [text]
key aid
Offers(qid,aid) -- question [qid] offers answer [aid]
key (qid,aid)
fk qid to Question, fk aid to Answer
Ok(qid,aid) -- [aid] is the right answer to [qid]
key (qid,aid)
fk (qid,aid) to Offers
fk qid to Question, fk aid to Answer
这是一个简单的设计。碰巧没有 FK 循环。 (另外,问题和回答的 FK 不需要声明/明确,因为它们是要约的 FK 及其 FK 的后果。)
可以通过多种方式组合这些。您选择了一些东西(具有 FK 循环),例如:
MC(qid,text,aid)
-- question [qid] has answer [aid]
AND [aid] is the right answer to [qid]
MC_choice(aid,qid,text)
-- question [qid] offers answer [aid]
AND answer [aid] has text [text])
因为表的成员条件的 AND 是表的 NATURAL JOIN 的成员条件,
MC = Question NATURAL JOIN Ok
MC_choice = Offers NATURAL JOIN Answer
1)如果我要坚持这个递归外键引用,如何保存到数据库中?
在 SQL 中,如果声明的 FK 子行有一些列 NULL(还有其他模式),则 DBMS 认为约束已满足。因此,允许 MC 辅助可以为空。先插入一个带有NULLaid的MC qid,然后把qid和aid插入MC_choice,然后把MC NULL改成qid的MC_choiceaid。
但在典型的 SQL DBMS 中,您不能有 FK 循环。 (没有充分的理由。)如果您的意思是无论如何都想要这些表中的这些列,那么您可以删除 FK 声明但添加触发器。 SQL DBMS 只提供少数声明性约束形式;一般来说,还必须使用触发器来表达约束。
2) 这种设计有意义吗?我觉得功能依赖在争论它,但在实践中似乎很麻烦。
这很麻烦,但正确答案是其问题的函数这一事实并不意味着答案必须与他们的问题放在任何特定的表格中。
3) Rails 中的 ActiveRecord 是否支持这种操作?
是的。使 MC 模型(表)辅助字段(列)可为空。
4) 如果上面的架构很傻,我应该如何设计我的表?
not best 和 silly 之间有一定的距离,即笨重并不意味着愚蠢,而只是使用上面的设计,或者这个变体:
MC = Question
MC_choice = Offers NATURAL JOIN Answer
MC_ok = Ok
始终尝试找出最简单的表谓词(成员资格标准、句子模板、填写-[命名-]空白语句),以用于描述您的情况。您可能希望将多个收集到一个表中,但对于函数关系的去向,可能有多个选择。