对于在线调查问卷,如何设计数据库以跟踪所有用户的尝试?

时间:2013-05-24 04:20:42

标签: database-design

我们有一个网络应用程序,用户可以在这里进行在线考试。

考试管理员将创建一份问卷。问卷可以有很多问题。每个问题都是一个多项选择题(MCQ)。

让我们说管理员创建一个包含10个问题的调查问卷。用户尝试这些问题。现在,与真实考试不同,用户可以多次尝试单一问卷。我们必须跟踪他的所有尝试。

e.g。

    User_id     Questionnaire_id    question_id answer  attempt_date    attempt_no
1       1           1       a   1 June 2013 1
1       1           2       b   1 June 2013 1

1       1           1       c   2 June 2013 2
1       1           2       d   2 June 2013 2

现在也可能发生这样的情况:用户尝试过两次相同的问题后,管理员可以从同一个问卷中删除一个问题,但是用户尝试历史记录仍然应该参考,以便用户可以在他的尝试历史中看到他的那个问题。管理员删除该问题。

如果用户现在尝试更改此问卷,他应该只看到1个问题。

    User_id     Questionnaire_id    question_id answer  attempt_date    attempt_no
1       1           1       a   3 June 2013 3

此外,在此用户修改了部分问题后,用户尝试历史记录应在修改前显示问题,而任何新尝试都应显示已修改的问题。

我们如何在数据库级别管理这个?

我的第一感觉是,

对于删除操作,请勿进行物理删除,只需使问题处于非活动状态,以便历史记录仍能跟踪用户的尝试。

对于修改,请为问题创建版本,每次新尝试都会刷新每个问题和历史记录的最新版本,并在尝试时保留对问题版本的引用。

1 个答案:

答案 0 :(得分:3)

(对不起,我使用“考试”代替“问卷” - 后者对我的图表来说太笨拙了。)

是的,您必须进行某种形式的版本控制。隔离的版本控制对象很容易,但在对象之间进行版本控制链接可能会很快变得复杂。为了保持它(相对)简单,你可以这样做:

enter image description here

这形成了一个层次结构,可以自下而上地对其进行版本化以响应变化:

  • 修改答案的文字,添加或删除答案,或修改问题的文本都被视为对问题的修改。
  • 除了添加或删除问题外,还会将其视为考试的修改。
  • 通过创建新的考试版本并在应用适当的更改时复制旧考试版本下的完整树来完成。

这种版本化的“分层”方法,即响应任何树节点的修改而创建整个树的新版本,可能有点浪费,但推理和实现起来相当简单。

另一种方法是显式版本化子对象和链接,然后仔细查询,以便仅检索特定的“及时快照”。这显然需要一个明显不同的数据库模式...


顺便提一下,您会注意到识别关系和生成的复合主键的大量使用。这对于正确建模USER_ANSWER底部的菱形依赖性是必要的,因此用户无法提供不属于考试的答案。

QUESTION.ANSWER_NO有助于识别正确的答案(这假定为MATCH SIMPLE个外键 - 另请参阅this post)。

ATTEMPT.TIMESTAMP是用户开始尝试的日期/时间。连同给出个别答案的时间,可以重新创建完整的“时间表”。考试时间是尝试开始和最后一个答案之间的时间。

USER_ANSWER.ANSWER_NO将保留在主键外,因此在同一次尝试中,不能为同一个问题提供两个不同的答案。

DELETED标志存在于考试版本中,而不是考试本身,因此如果您取消删除考试,将会有一个历史记录。您甚至可以多次删除和取消删除相同的考试。