5

问候堆垛机,

我正在尝试为允许用户创建调查并将其展示给公众的应用程序提出最佳数据库模式。大多数调查(但不是全部)将包括一堆“标准”人口统计字段,例如名字、姓氏等。当然,用户可以创建无限数量的“自定义”问题。

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

Survey
  ID
  SurveyName

SurveyQuestions
  SurveyID
  Question

Responses
  SurveyID
  SubmitTime

ResponseAnswers
  SurveyID
  Question
  Answer

但这每次我想查询数据时都会很糟糕。它似乎危险地接近内平台效应

一个改进是在响应表中包含尽可能多的字段:

Responses
  SurveyID
  SubmitTime
  FirstName
  LastName
  Birthdate
  [...]

然后,至少从这些常见列中查询数据是很简单的,我可以查询,比如说,每个回答过他们出生日期的调查的人的平均年龄。

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

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

4

4 回答 4

5

您的第一个模式是两者中更好的选择。此时,您不必担心性能问题。担心做出好的、灵活的、可扩展的设计。您可以稍后使用各种技巧来缓存数据并加快查询速度。使用不太灵活的数据库模式来解决甚至可能无法实现的性能问题是一个糟糕的决定。

此外,许多(可能是大多数)调查结果仅由少数人(活动组织者、管理员等)定期查看,因此您不会一直在数据库中查询所有结果。即使你是,表现也会很好。无论如何,您可能会以某种方式对结果进行分页。

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

这是您提供的架构的略微修改版本。我假设您可以弄清楚哪些数据类型在哪里:-)

    调查
      调查 ID(索引)
      标题

    问题
      question_id(索引,自动递增)
      survey_id(链接到调查->survey_id)
      问题

    回应
      response_id(索引,自动递增)
      survey_id(链接到调查->survey_id)
      提交时间

    答案
      answer_id(索引,自动递增)
      question_id(链接到 questions-question_id)
      回答
于 2009-01-09T20:23:39.103 回答
1

我建议您始终对数据库模式采用标准化方法,然后再决定是否出于性能原因需要创建解决方案。过早的优化可能很危险。过早的数据库反规范化可能是灾难性的!

我建议您坚持使用原始模式,然后在必要时创建一个报告表,该表是您的规范化模式的非规范化版本。

于 2009-01-09T19:59:08.467 回答
1

一项可能有助于或可能不会帮助简化事情的更改是不将 ResponseAnswers 链接回 SurveyID。相反,为每个响应和每个问题创建一个 ID,并让您的 ResponseAnswers 表包含字段 ResponseID、QuestionID、Answer。尽管这需要为每个单元保留唯一的标识符,但这将有助于使事情更加规范化。响应答案不需要与他们正在回答的调查相关联,只需他们正在回答的特定问题和与之关联的响应信息。

于 2009-01-09T20:08:56.717 回答
0

我在以前的工作中创建了一个客户调查系统,并提出了一个与您所拥有的非常相似的架构。它用于发送调查(在纸上)并将响应制成表格。

几个小区别:

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

  • 调查附带了一组问题,因此一个问题可以用于多个调查,并且可以独立于它出现的调查进行分析。

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

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

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

于 2009-01-09T20:11:16.103 回答