问候堆垛机,
我正在尝试为应用程序提供最佳数据库架构,以便用户创建调查并将其呈现给公众。有大量“标准”人口统计字段,大多数调查(但不是全部)将包括,如名字,姓氏等。当然,用户可以创建无限数量的“自定义”问题。
我想到的第一件事是这样的:
Survey
ID
SurveyName
SurveyQuestions
SurveyID
Question
Responses
SurveyID
SubmitTime
ResponseAnswers
SurveyID
Question
Answer
但每次我想查询数据时,这都会很糟糕。它似乎危险地接近Inner Platform Effect
改进将包括我在响应表中预先考虑的多个字段:
Responses
SurveyID
SubmitTime
FirstName
LastName
Birthdate
[...]
然后,至少对来自这些公共列的数据的查询很简单,我可以查询,例如,每个回答任何调查的人的平均年龄。
但似乎这会使代码复杂化一些。现在,要查看调查中询问的问题,我必须检查哪些常见响应字段已启用(使用,我猜测,调查中的位域)以及SurveyQuestions表中的内容。我不得不担心特殊情况,例如,如果有人试图创建一个“自定义”问题,该问题会在“回复”表中复制“常见”问题。
这是我能做的最好的吗?我错过了什么吗?
答案 0 :(得分: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)
我建议您始终对数据库架构采用规范化方法,然后决定是否需要根据性能原因创建解决方案。过早优化可能很危险。过早的数据库反规范化可能是灾难性的!
我建议您坚持使用原始架构,然后在必要时创建一个报告表,该表是规范化架构的非规范化版本。
答案 2 :(得分:1)
可能会或可能不会简化事情的一个变化是不将ResponseAnswers链接回SurveyID。而是,为每个响应和每个问题创建一个ID,并让ResponseAnswers表包含ResponseID,QuestionID,Answer字段。虽然这需要为每个单元保留唯一的标识符,但这有助于使事情更加标准化。答案答案无需与他们仅回答他们正在回答的具体问题的调查以及他们所关联的回复信息相关联。
答案 3 :(得分:0)
我在之前的工作中创建了一个客户调查系统,并提出了一个与您的模式非常相似的模式。它被用来发送调查(在纸面上)并将回复列表。
一些细微差别:
调查非匿名,这在印刷表格中非常明确。这也意味着您的示例中的人口统计数据是事先知道的。
调查附有一系列问题,因此可以在多个调查中使用一个问题,并独立于其出现的调查进行分析。
处理不同类型的问题很有意思 - 我们有1-3级(例如,更差/更好/更好),1-5级(非常糟糕,糟糕,好,好,非常好),是/否,和评论。
有处理评论的特殊代码,但其他问题类型通过一个问题类型表和另一个每种类型的有效答案表来统一处理。
为了使查询更容易,您可以根据调查ID和问题ID创建一个返回响应的函数。