【问题标题】:normalization of Repeating Groups重复组的标准化
【发布时间】:2015-03-24 20:06:17
【问题描述】:

我的数据由问题和答案组成。它还显示答案的 versionNr 是什么,并显示哪些人更改了哪个答案。 有些问题可能有相同的答案。

questionID    Question      Answer       VersionNr    User            date
     1        Who is....?   W.H. Smith     1.0        ...@test.com   1/1/14          
                                           1.1        ...@test.com   3/8/14

     2        What is...?   3%             1.0        ...@test.com   1/2/14

RG = 重复组
粗体 = 复合键/主键

0NF:
(questionID, question, AnswerID, answer,RG{versionNr, user, date}

1NF:
questionID、问题、AnswerID、答案)
(questionID、AnswerIDVersionNr、用户、日期)

2NF/3NF:
Q(questionID, question, AnswerID)
Ans(AnswerID, answer)
版本(问题 ID、AnswerIDVersionNr、用户、日期)

我的问题是我是否应该从版本中删除 questionID,因为 versionNr、日期和用户提供了关于答案而不是问题的信息。

【问题讨论】:

  • 你说两个问题可能有相同的答案是什么意思?例如,如果您的意思是这是一个数学测验,并且您可能有两个问题的答案都是“4”,那么我会说这无关紧要。您不希望两个问题都指向同一个答案记录,因为如果有人意识到其中一个答案是错误的并且应该是“3”怎么办?好吧,也许你的答案记录是不可变的,因为如果有变化,你就会创建一个新版本。但是寻找巧合的重复,那么,什么,你可以保存创建记录?,通常不是一个好主意。

标签: database database-design relational-database primary-key normalization


【解决方案1】:

如果我正确理解您的问题,我相信您可以执行以下操作来实现有效的 3NF 架构。

Q(questionID, question)

Ans(AnswerID,answer,QuestionID)

版本(VersionNrAnswerID用户、日期)

(斜体为外键)

所以,版本的主键是三元组 {VersionNr,AnswerID,User)。请说明我的解决方案是否有问题。

所以,总而言之,不,您不需要在版本中包含 questionID,因为您可以通过连接找到它。

更新

我想我理解你的问题,我相信正确的解决方案如下。

Q(questionID,question)

Ans(AnswerID,answer)

版本(QuestionID,AnswerID,VersionNr,user,date)

实际上,答案和问题之间的关系是多对多的,因为许多答案与许多问题相关联。因此,您可以使用 Version 作为中间表来构建这种多对多关系。

此外,您可以在该中间表中添加版本号、用户和日期,以获得所有必要的信息。

【讨论】:

  • 我认为主键就是 (answerID, versionNr)。如果有人更新答案,应该有一个新的版本号。如果这不是真的,那么添加“用户”不一定有帮助。如果用户 A 输入答案,用户 B 更改它,然后用户 A 再次更改它会怎样?除非有某种保证,每个用户只能更改一次答案,否则在密钥中包含 user 无助于使其唯一。
  • 我不明白他是希望能够找到每个用户的最新答案,还是一般的最新答案。我相信他希望能够找到每个用户的最新答案。因此,仅 VersionNr 和 AnswerID 是不够的,因为以相同方式(并且具有相同版本)回答相同问题的两个用户在版本表中将具有相同的主键。
  • 哦,可以。我在想用户正在更新被认为是“正确答案”的内容。可能每个用户都在更新自己的答案。其实这可能更有意义。就像这是一个测验,我不确定用户是老师还是学生。
【解决方案2】:

如果一个答案记录可以有多个版本记录,那么是的,QuestionID 不应该在 Version 中,因为它是冗余数据:您始终可以通过查找 Answer 记录来知道一个版本的 QuestionID。

也就是说,我不清楚您要建模什么。当您说用户可以更改答案时,您的意思是这是一个测验,用户可以更改“正确答案”是什么?或者您的意思是他们可以更改他们对测验或调查的回答?

但是,如果一个答案有多个版本记录,那么您不是在记录每个步骤的答案是什么,您只是在记录谁进行了更改。也许这就是您需要了解的所有内容。但是,如果您想记录每个版本的答案,那么答案和版本应该合并到一个表中。在这种情况下,您需要在答案/版本记录中使用 questionID,否则您将无法知道除了最新答案之外的任何答案是针对哪个问题的。

如果想法是每个问题只有一个答案记录,然后有多个版本,那么问题和答案应该合并到一个记录中。好吧,您说几个问题可以共享相同的答案。正如我在评论中问的那样,这是什么意思?您是否在谈论巧合的相同答案,例如问题是“2 + 2是多少?”另一个是“16 的平方根是多少?”两个答案都恰好是 4?或者你的意思是他们真的是同一个答案,如果一个问题的答案改变了,另一个问题的答案在逻辑上和不可避免地必须改变成同样的事情?比如,“谁是美国现任副总统?”和“如果美国总统死了,谁会成为总统?”

我认为逻辑架构是这样的:

Question (questionID, question_text)
Answer (answerID, questionID, version_number, answer_text, user, change_date)

那么当前的答案是

select answer_text
from answer
where questionID=@qid
  and version_number=(select max(version_number) from answer
    where questionID=@qid)

这不需要冗余数据。

为了性能和简单性,一个明显的反规范化是将当前答案的 answerID 放入问题记录中。

【讨论】:

  • 我的数据可以看做FAQ。我数据中的很多问题都有相同的答案。确实,我不想保存旧版本的答案。 answerID不应该留在问题中吗?因为问题只有1个答案,而答案可以关联多个问题。这意味着答案和问题之间存在 (1:N) 关系。
  • 我不明白 2 个问题如何共享一个答案。你说这是FAQ?因此,可能有多个问题实际上是同一个问题,只是措辞不同?就像一个人问,“我怎样才能制造月球火箭?”,然后你发布一个答案,然后另一个人问,“我怎样才能去月球旅行?”,你说,哦,那是一样的作为另一个问题,并指出相同的答案?如果是这种情况,并且如果您也有多个版本的答案,那么不是 1:M,而是 M:N:每个问题都有多个答案,每个答案都有多个问题。
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 2021-05-24
  • 2019-12-27
  • 2020-07-02
  • 2021-05-13
  • 2021-04-05
  • 2022-01-20
相关资源
最近更新 更多