从多个候选键中选择

时间:2012-01-31 15:55:12

标签: mysql database-design

我可能缺乏数学背景来为自己找到合适的答案。我有这样的表设置(省略不相关的列):

Questions
   queID

Answers
   queID
   ansID

用户可以通过选择某些问题来创建测验。答案是用户可以从每个问题中选择的答案。

Sessions
   sessID

当客户挑选一组要回答的问题时,会创建一个“会话”。

SessionQuestions
   sqID
   sessID
   queID

这些是用户为给定会话选择的问题。

我遇到障碍的地方是SessionAnswers级别。问题的答案顺序可以是随机的。也就是说,具有A,B,C的默认答案顺序的多项选择题可以显示为用户的C,B,A。然而,每当他们再次查看该问题时,它仍然需要是C,B,A,因此需要存储最终订单。我的暂定表是:

SessionAnswers
   sqID
   ansID
   saOrder

问题是sqID指向queID,但ansID也是如此。这意味着我可以在此表或sessID上使用sqID。我不确定选哪一个。此设置仍然可以将ansID映射到一个答案,该答案映射到一个甚至不在SessionQuestions上的问题,这是不正确的。我可以改进设置以避免这种情况吗?

1 个答案:

答案 0 :(得分:3)

钻石形状的依赖性受益于自然键(与代理相反)。自然键可以“合并”在“钻石”的底部,产生正确的参照完整性行为。

在您的情况下,使用SessionQuestions{sessID, queID}而不是代理{sqID})中的自然键,可以将所有父键“组件”传播到两个“边缘”钻石,因此不可能有一个会话回答,其问题不在同一会话中。

您的模型应如下所示:

enter image description here

注意:由于每个会话的答案也可以按顺序识别,因此在SessionAnswers中需要一个额外的备用键(上面用'U1'表示)。请注意,该密钥中不应包含queIDansID - 否则将允许两个不同的答案占用相同的“广告位”。

---编辑---

@tandu,我看到你接受了我的答案所以我应该在我领先的时候停下来;)但是我仍然想提出另一种设计:

enter image description here

这可以让您保持 历史和订单。当用户输入一组答案时,它们将记录在版本= 1的SessionAnswers中。如果更改了一个或多个答案,则会创建一个版本= 2,依此类推......

每个会话版本都有2个与之关联的集合:

  • 一组独特的问题,每个问题都有一个答案(通过PK强制执行)。
  • 用于订购的一组“插槽”(通过备用密钥强制执行)。

由于两者都包含在同一个表中,这意味着每个问题都只映射到一个插槽,每个插槽只映射一个问题。

顺便说一句,这也使您可以根据需要更改版本之间的顺序。