【问题标题】:Database design for a survey [closed]调查的数据库设计[关闭]
【发布时间】:2010-12-18 09:03:46
【问题描述】:

我需要创建一个调查,其中答案存储在数据库中。我只是想知道在数据库中实现这一点的最佳方法是什么,特别是所需的表。该调查包含不同类型的问题。例如:cmets 的文本字段、多项选择题以及可能包含多个答案的问题(即选中所有适用的选项)。

我提出了两种可能的解决方案:

  1. 创建一个包含 每个调查的答案 提交。每列将 对应于来自的答案 民意调查。即SurveyID、Answer1、 答案2,答案3

    我认为这不是最好的方法 因为有很多问题 在这项调查中,似乎不是很 如果调查要更改,则灵活。

  2. 我想到的另一件事是 创建问题表和答案 桌子。问题表将 包含所有问题 民意调查。答案表将包含 调查中的个人答案, 每一行都与一个问题相关联。

    一个简单的例子:

    tblSurvey:SurveyID

    tblQuestion:QuestionID、SurveyID、QuestionType、问题

    tblAnswer:AnswerID、UserIDQuestionID、Answer

    tblUser:用户 ID、用户名

    我的问题是 可能有很多答案 使答案表非常大。 我不确定那是不是很棒 说到性能。

如果有任何想法和建议,我将不胜感激。

【问题讨论】:

  • “相当巨大”是多少?给我们一个估计,我们说的是一百万还是一亿?
  • SQL 服务器实际上是为处理大量数据而设计的。使用您所讨论的方案应该不会有太多麻烦。

标签: sql database-design


【解决方案1】:

我认为您的模型 #2 很好,但是您可以查看更复杂的模型,该模型存储问题和预先制作的答案(提供的答案)并允许它们在不同的调查中重复使用。

- 一项调查可以有很多问题;一个问题可以在许多调查中(重新)使用。
- 可以为许多问题提供一个(预制)答案。一个问题可以提供多个答案。一个问题可以在不同的调查中提供不同的答案。可以在不同的调查中为不同的问题提供答案。有一个默认的“Other”答案,如果一个人选择了other,她的答案就会被记录到Answer.OtherText中。
- 一个人可以参与多个调查,一个人只能回答一次调查中的特定问题。

【讨论】:

  • 你用什么工具来制作数据库架构?
  • 您也可以使用draw.io 它是免费的,无需注册且易于使用。
  • 为什么我们有Survey_Question_AnswerAnswerAnswer 还不够吗?
  • Abubakar Ahmad,Survey_Question_Answer 用于从用户中挑选多个预制答案.. 一个问题..
  • 我觉得Answer够了,Survery_question_answer是多余的
【解决方案2】:

我的设计如下所示。

最新的创建脚本在https://gist.github.com/durrantm/1e618164fd4acf91e372

脚本和 mysql workbench.mwb 文件也可以在
https://github.com/durrantm/survey获得

【讨论】:

  • 嗨,我喜欢你的设计。请问表有任何数据样本(转储)吗?真的很感激
  • 嗨!首先感谢您的工作,这太棒了!您是否考虑过其中一个模板中的层次结构?用户通常会提供有关其领导者的信息,而这些领导者具有有关其领导者的信息等。用户在不同的部门(人力资源、生产)工作,这些部门也可以有层次结构。因此,在报告过程中,通常需要区分这些组织级别。
  • @michael:这真的很有帮助。你有使用spring的java参考/github链接吗?
  • 我仍在尝试找出option_groupsoption_choices 之间的区别以及用例是什么。
  • @PHPnoob 我认为,顾名思义,这只是 groups 选项。所以,如果你可以,例如率在 1 到 5 之间,然后 option_groups 应该允许你完全正确,如果我做对了。
【解决方案3】:

绝对是选项#2,我认为您可能对当前架构有疏忽,您可能想要另一个表:

+-----------+
| tblSurvey |
|-----------|
| SurveyId  |
+-----------+

+--------------+
| tblQuestion  |
|--------------|
| QuestionID   |
| SurveyID     |
| QuestionType |
| Question     |
+--------------+

+--------------+
| tblAnswer    |
|--------------|
| AnswerID     |
| QuestionID   |
| Answer       |
+--------------+

+------------------+
| tblUsersAnswer   |
|------------------|
| UserAnswerID     |
| AnswerID         |
| UserID           |
| Response         |
+------------------+

+-----------+
| tblUser   |
|-----------|
| UserID    |
| UserName  |
+-----------+

每个问题可能会有一组可供用户选择的答案,然后将在另一个表中跟踪实际的答案。

数据库旨在存储大量数据,并且大多数可扩展性很好。不再需要使用较小的normal form 来节省空间。

【讨论】:

  • 嗨,我有一个问题。 SurveyId 不应该也出现在答案表中,或者至少不应该与调查的版本控制时间相匹配的时间戳吗?如果您在原始调查中插入了一个问题,questionIds 将会改变,并且答案将变得无法识别。或者如果它是多余的,你能解释一下吗?
【解决方案4】:

作为一般规则,根据用户可以更改的内容(例如向调查中添加问题)修改架构应该被认为是相当臭的。在某些情况下它可能是合适的,特别是在处理大量数据时,但在深入研究之前要知道你正在进入什么。每个调查只有一个“响应”表意味着添加或删除问题可能非常昂贵,并且很难以与问题无关的方式进行分析。

我认为你的第二种方法是最好的,但如果你确定你会遇到很多规模问题,那么过去对我有用的一件事是混合方法:

  1. 创建详细的响应表以存储每个问题的响应,如您在 2 中所述。此数据通常不会直接从您的应用程序中查询,但会用于生成报告表的摘要数据。您可能还希望对这些数据实施某种形式的归档或删除。
  2. 如有必要,还可以从 1 创建响应表。每当用户想要查看简单的结果表时,都可以使用此功能。
  3. 对于需要为报告目的进行的任何分析,安排作业以根据 1 中的数据创建额外的摘要数据。

这绝对需要更多的工作来实现,所以我真的不建议这样做,除非你确定这张表会遇到大规模的问题。

【讨论】:

    【解决方案5】:

    第二种方法最好。

    如果你想进一步规范化它,你可以为问题类型创建一个表格

    简单的事情是:

    • 将数据库和日志放在自己的磁盘上,而不是默认都在 C 上
    • 根据需要创建尽可能大的数据库,这样您就不会在数据库增长时出现暂停

    我们在 SQL Server 表中有数百万行的日志表。

    【讨论】:

      【解决方案6】:

      No 2 看起来不错。

      对于只有 4 列的表,即使有几百万行也不成问题。当然,这取决于您使用的数据库。如果是 SQL Server 之类的,那就没问题了。

      您可能希望在 tblAnswer 表的 QuestionID 字段上创建索引。

      当然,您需要指定您正在使用的数据库以及估计的容量。

      【讨论】:

        【解决方案7】:

        您可以选择将整个表单存储为 JSON 字符串。

        不确定您的要求,但这种方法在某些情况下可行。

        【讨论】:

          【解决方案8】:

          对于一个简单的调查来说看起来很完整。不要忘记为“开放价值观”添加一个表格,客户可以在其中通过文本框提供他的意见。将该表与外键链接到您的答案,并在所有关系列上放置索引以提高性能。

          【讨论】:

          • 我不能也将 cmets 放入答案表中有什么原因吗?
          【解决方案9】:

          数字 2 是正确的。使用正确的设计,直到并且除非您检测到性能问题。大多数 RDBMS 对窄但很长的表不会有问题。

          【讨论】:

            【解决方案10】:

            拥有一个大的答案表本身不是问题。只要索引和约束定义明确,你应该没问题。您的第二个架构对我来说看起来不错。

            【讨论】:

              【解决方案11】:

              鉴于正确的索引,您的第二个解决方案是规范化的,并且适用于传统的关系数据库系统。

              我不知道巨大有多大,但它应该毫无问题地容纳几百万个答案。

              【讨论】:

                猜你喜欢
                • 2018-05-02
                • 2012-04-25
                • 2010-09-22
                • 1970-01-01
                • 2014-03-04
                • 2011-01-02
                • 2011-11-08
                • 2010-09-13
                相关资源
                最近更新 更多