【问题标题】:SQL - Survey Data, Table Schema Design for looped survey questionsSQL - 调查数据,循环调查问题的表模式设计
【发布时间】:2019-07-16 23:20:05
【问题描述】:

假设我们进行了一项调查,其中一些问题涉及多个实体。

例如:
汽车品牌 = [品牌 1、品牌 2、品牌 3、品牌 4...]

将针对每个汽车品牌(循环)询问此问题。
Question Q01 = (Scale 1-10) 你觉得【汽车品牌】的车靠谱吗?
问题 Q02 =(1-10 级)您认为 [汽车品牌] 的汽车是否物有所值?
...

我正在设计一个架构,它将为一些基于 Web 的分析工具提供支持,因此查询性能很重要。

架构将是 3 个表:记录、问题、答案

答案表有两种方法:

A) 表格:答案

QuestionId | AnswerValue | BrandOption 
   Q01     |      7      |      1
   Q01     |      5      |      2
   Q01     |      4      |      3
   Q01     |      8      |      4

B) 表格:答案

QuestionId | AnswerValue
  Q01-1    |     7
  Q01-2    |     5
  Q01-3    |     4
  Q01-4    |     8

查询可以一次针对一个品牌,也可以针对所有品牌,两个查询的优先级相同。

如果我需要执行 group by 之类的操作,选项 A 似乎给了我一些优势,但是如果大多数查询都是针对特定品牌的,那么选项 B 似乎更有效。

想法?

【问题讨论】:

  • 选项 A 允许查询具有给定 questionID 的所有答案,而无需删除一些'-';您可能希望汇总给定问题而不是组合(即所有品牌中有多少赞成票与反对票)。是什么让选项 B 更有效?使用 (brandoption, questionid) 上的索引,您仍然可以非常高效。

标签: sql postgresql database-design


【解决方案1】:

选项 A 更好,即使您现在看不到它。
在单个数据库“单元格”中存储多个值是一个错误(尽管不幸的是,这是一个非常常见的错误)——更不用说它违反了first normal form——它明确指出每列只能包含每行中的单个原子值(尽管原始规则使用不同的术语)。

缺点很多,其中一些很关键,包括(但不限于):

  • 您失去了使用正确数据类型的能力 - 存储在一起的两个 int 必须存储为与 int 不同的数据类型。
  • 您可能无法验证您的数据实际上是否正确,或者不同部分可以转换为正确的数据类型(现在大多数数据库都支持检查约束,但不是全部(是的,MySql,我是把我的手指指向你!))
  • 您失去了分别对数据的每个部分强制执行唯一性的能力。
  • 您不能将数据的不同部分用作外键约束的基础

这个列表还在继续 - 但我认为现在任何人都应该了解情况 - 每次都应该使用数据库列来为每一行存储一个值。

【讨论】:

  • 我要提到在单个字段中存储多个值也打破了正常形式。强有力的答案。
  • 是的,我明白了,谢谢你的回答。然而,这个想法不是在问题列上存储两个值,而是实际上重命名问题 id 并将它们视为品牌之间独特的不同问题,如果查询特定品牌,想法是避免使用 where 子句,但我同意, 选项 A 似乎更有意义
  • 如果你想要一个单列行标识符,你总是可以添加一个代理键(但不要忘记确保实际值的行唯一性)——但是仅仅因为它有一个不同的汽车品牌可能会引入诸如问题不匹配之类的问题,即使是 Do you think Ferrari cars are reliable?Do you think Aston-Martin cars are reliant? 这样的自动完成拼写错误我认为将问题的文本与汽车品牌分开是一个更好、更安全的选择。
【解决方案2】:

我认为第一个版本更可取。它可以更轻松地为单个品牌寻找不同问题的答案,以及跨品牌寻找相同问题的答案。

修改问题 ID 似乎是一个糟糕的替代品。一方面,它排除了与questions 表和brands 表的简单外键关系。我是显式外键关系的忠实拥护者。

当然,要完成这项工作,您需要一种方法来存储“无品牌”或“品牌不相关”。一种方法是使用NULL 来回答此类问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-26
    • 2023-01-17
    • 2012-07-31
    • 1970-01-01
    • 2012-04-25
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多