【问题标题】:Schema design for when users can define fields用户何时可以定义字段的架构设计
【发布时间】:2009-01-13 18:25:28
【问题描述】:

问候堆垛机,

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

我首先想到的是这样的:

Survey
  ID
  SurveyName

SurveyQuestions
  SurveyID
  Question

Responses
  SurveyID
  SubmitTime

ResponseAnswers
  SurveyID
  Question
  Answer

但是每次我想查询数据时都会很糟糕。而且它似乎危险地接近Inner Platform Effect

改进方法是在响应表中包含我能想到的尽可能多的字段:

Responses
  SurveyID
  SubmitTime
  FirstName
  LastName
  Birthdate
  [...]

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

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

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

【问题讨论】:

  • 我可以建议您将问题的标题更改为“什么是调查系统的最佳数据库架构?”

标签: mysql database database-design schema


【解决方案1】:

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

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

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

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

调查 调查 ID(索引) 标题 问题 question_id(索引,自动递增) survey_id(链接到调查->survey_id) 问题 回应 response_id(索引,自动递增) survey_id(链接到调查->survey_id) 提交时间 答案 answer_id(索引,自动递增) question_id(链接到 questions-question_id) 回答

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        几个小区别:

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

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

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

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

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

        【讨论】:

        • 好点。是的,我忽略了处理不同类型的问题来集中我的帖子,但我还必须解决这个问题以及对用户定义的验证规则的支持。
        猜你喜欢
        • 1970-01-01
        • 2013-08-29
        • 2011-07-03
        • 1970-01-01
        • 2013-05-31
        • 2012-03-13
        • 2014-01-13
        • 2018-10-24
        • 2016-04-29
        相关资源
        最近更新 更多