2009-01-09 64 views
5

问候堆垛机,架构设计时,用户可以自定义字段

我试图想出一个应用程序,允许用户创建调查,并提交给公众最好的数据库模式。大多数调查(但不是全部)都会包含一系列“标准”人口统计字段,例如名字,姓氏等。当然,用户可以创建无限数量的“自定义”问题。

我想到的第一件事情是这样的:

Survey 
    ID 
    SurveyName 

SurveyQuestions 
    SurveyID 
    Question 

Responses 
    SurveyID 
    SubmitTime 

ResponseAnswers 
    SurveyID 
    Question 
    Answer 

但是,这是怎么回事我想查询出来的数据,每次吸。它似乎危险地接近Inner Platform Effect

的改进将包括尽可能多的领域,我可以事先在响应表认为:

Responses 
    SurveyID 
    SubmitTime 
    FirstName 
    LastName 
    Birthdate 
    [...] 

然后从这些公共列至少查询的数据直截了当,并且我可以查询,例如,曾经回答任何调查问卷的人的平均年龄。

但似乎这样会使代码复杂一点。现在要查看调查中询问哪些问题,我必须检查哪些常见响应字段已启用(我猜测,使用Survey中的一个位域)以及SurveyQuestions表中的内容。而且我不得不担心特殊情况,例如有人试图在“答复”表中创建一个重复“常见”问题的“自定义”问题。

这是我能做的最好的吗?我错过了什么吗?

+0

我可以建议将您的问题的标题更改为“什么是调查系统的最佳数据库模式?” – 2009-01-09 20:29:28

回答

5

您的第一个模式是两者中较好的选择。此时,您不应该担心性能问题。担心做出一个好的,灵活的,可扩展的设计。您稍后可以使用各种技巧来缓存数据并加快查询速度。使用不太灵活的数据库模式来解决甚至可能无法实现的性能问题是一个不好的决定。此外,很多(也许是大多数)调查结果只能定期查看,并且只有少数人(活动组织者,管理员等)查看,所以您不会经常查询数据库中的所有结果。即使你是,表现也会很好。无论如何,你可能会以某种方式对结果进行分页。

第一个模式更加灵活。默认情况下,您可以包括名称和地址等问题,但对于匿名调查,您可以根本不创建它们。如果调查创建者只想查看每个人对五百个问题中三个问题的答案,那么这是一个非常简单的SQL查询。您可以设置级联删除,以在调查被删除时自动删除回复和问题。使用此架构生成统计信息也会更容易。

以下是您提供的模式的略微修改版本。我想你可以找出哪些数据类型去哪里:-)

 
    surveys 
     survey_id (index) 
     title 

    questions 
     question_id (index, auto increment) 
     survey_id (link to surveys->survey_id) 
     question 

    responses 
     response_id (index, auto increment) 
     survey_id (link to surveys->survey_id) 
     submit_time 

    answers 
     answer_id (index, auto increment) 
     question_id (link to questions-question_id) 
     answer 
1

我建议你总是采用规范化的方法处理数据库模式,然后再决定是否需要为性能原因创建解决方案。过早优化可能是危险的。过早的数据库去归一化可能是灾难性的!

我建议你坚持使用原始模式,如果有必要,稍后创建一个报表,它是规范化模式的非标准化版本。

1

可能或不可能帮助简化事情的一个变化是不将ResponseAnswers链接回SurveyID。而是为每个回答和每个问题创建一个ID,并让您的ResponseAnswers表包含字段ResponseID,QuestionID,Answer。虽然这将需要为每个单元保留唯一的标识符,这将有助于使事情更加标准化。答案答案不需要与他们回答的调查相关联,而只是回答他们正在回答的具体问题以及他们相关的答复信息。

+0

是的,这是有道理的。 – Eli 2009-01-09 20:16:19

0

我在以前的工作中创建了一个客户调查系统,并提出了一个与您拥有的模式非常相似的模式。它被用来发送调查(在纸上)并列出响应。

一对夫妇的细微差别:

  • 调查是不是匿名,这被做在印制的表格非常清楚。这也意味着您的示例中的人口统计数据是事先知道的。

  • 由于调查中附带了一系列问题,因此可以在多个调查中使用一个问题,并独立于其出现的调查进行分析。

  • 处理不同类型的问题变得有趣 - 我们有1-3个等级(例如,更差/相同/更好),1-5个等级(非常差,差,OK,良好,非常好),是/否和评论。

    有特殊的代码来处理评论,但其他问题类型的处理一般是有一个问题类型表和每个类型的有效答案的另一个表。

为了使查询更容易,您可以创建一个函数,根据调查ID和问题ID返回响应。

+0

好点。是的,我忽略了处理不同类型的问题以专注于我的文章,但我必须解决这些问题,并支持用户定义的验证规则。 – Eli 2009-01-09 20:14:51