8

我的数据库技能充其量只是平庸,我必须为调查数据设计一个数据模型。我对此进行了一些思考,现在我觉得我被困在某种EAV 模型和涉及数百个表的设计之间,每个表都有数百列(和数千条记录)。必须有更好的方法来做到这一点,我希望这个论坛上的聪明人能帮助我。

我的问题是:我应该如何在 RDBMS 中对调查问题的答案进行建模?必须使用 SQL Server。因此,应将替代数据存储系统排除在此讨论之外。(当然,有些应该并且将会被评估,但请不要在这里。)我不需要整个数据模型的解决方案,现在我只对答案部分感兴趣。

我已经搜索了各种论坛,但我真的找不到解决方案。如果它已经在其他地方给出,请原谅我并提供一个链接,以便我阅读。

关于我必须处理的数据的一些假设:

  1. 每个调查由 1 到 n 份问卷组成
  2. 每份问卷由 100-2,000 个问题组成(请忽略 2,000 个问题听起来确实需要回答很多...)
  3. 问题可以有多种类型:多项选择、自由文本、数字(如年龄、收入、百分比……)
  4. 每个调查涉及 10-200 个国家(这些不是受访者。受访者实际上是这些国家的人。)
  5. 根据问卷的类型,每个问卷由每个国家 100-20,000 名受访者回答。
  6. 一个国家可以调整调查问卷以进行调查,即添加、删除或编辑问题
  7. 一个国家的数据收集在该国家的单独数据库中。从一开始就不可能进行在线集成。
  8. 所有国家的数据都必须在以后整合。这意味着,例如,如果一个国家/地区删除了一个问题,该数据必须以某种方式从他们发送的内容中获取,以便在所有国家/地区实现统一设计
  9. 我将不得不编写集成和清理软件,它需要处理每个国家的数据
    1. 最后,需要将数据导出为平面文件、每个国家一个矩形网格和问卷。

我已经与来自不同背景的人讨论过这个话题,但还没有找到好的解决方案。我主要有两种意见。

  1. 习惯于使用平面文件(电子表格样式)进行数据处理和分析的领域专家投票支持具有大量表和列的非规范化结构,如上所述(每个国家和调查表 1 个表)。这对我来说听起来很糟糕,因为我了解到要避免使用宽表,在使用它时确定表中实际包含哪些列会很烦人,数据库将变得混乱,有数百个表(或者我什至需要设置多个数据库,每个数据库都有相似但有点不同的设计)等。
  2. OO 程序员投票支持高度“规范化”的设计,这将有效地导致一个包含所有受访者对所有问题的所有答案的中央表。此表需要包含 sql_variant 类型的列或具有不同类型的多个答案列,以存储不同类型的答案(多选、自由文本等)。前者本质上是 EAV 模型。我倾向于在这里关注 Joe Celko,他强烈反对使用它(他称之为 OTLT 或“一个真正的查找表”)。后者意味着每一行将包含设计不适用类型的空单元格。

我能想到的另一种选择是为每种答案类型创建一个表,即一个用于选择题,一个用于自由文本问题等。这不是那么通用,它会导致很多联合连接,我想想如果发明了新的答案类型,我将不得不添加一个表格。

很抱歉让您对所有这些文字感到厌烦,并感谢您的意见!

干杯,亚历克斯

PS:我在这里问了同样的问题:http ://www.eggheadcafe.com/community/aspnet/13/10242616/survey-data-model--how-to-avoid-eav-and-excessive-denormalization.aspx

4

4 回答 4

4

替代文字好吧,imgur 已关闭,所以我稍后会发布照片。

我认为这在关系模型中是完全可行的。我已经建立了一个 CDM 来展示我将如何做到这一点。

出境

定义一个国家的调查需要 4 个实体。一些家长调查、国家和问题清单。您的问题具有内部关系,因此当一个国家/地区“编辑”问题时,您可以跟踪该国家/地区提出的问题及其来自的问题。您需要的另一件事是可能的答案实体/表。每个问题都可能有一个相关的可能答案列表(多项选择或范围等)。这四个应该完全定义这个的“出站”方面。

入站

“入站”方面只有 2 个新实体,即答辩人和答案。受访者直截了当,只要您认识该人的人口统计数据,您就可以在此处包含与国家/地区的关系。每个受访者都在特定国家/地区回答了调查。(如果此人旅行或拥有双重国籍,则此人可能与答辩人 1:n)

答案是基本的;它要么是可能的答案列表中列出的选项之一,要么是提供的。不要全神贯注于答案可能是数字、日期等的事实。它是一个 FK 或一串字符。

报告

报告是所有这些的结合...您将选择一个国家和一项调查,获取问题和答案列表。

答案复杂性

取决于您要在哪里进行计算。如果您为用户提供的答案使用 Varchar2(4000) 列,则可以向问题添加一个属性来描述答案的数据类型。问:年龄?DT:(0 到 130)之间的整数。然后,您的集成层可以进行验证,而不是由数据库强制执行。或者您可以有 4 列,一列用于数字、日期、字符和 CLOB。您的集成层将确定要使用的列。当您报告这些答案时,您只需使用 Coalesce() 选择所有四列。

这是一个 EAV,因为“Answer”的数据类型有点模糊

不,这不对。

EAV 模型将实体分解为属性列表。像这样:

Entity     Attribute     Value
  1          Fname         Stephanie
  1          Lname         Page
  1          Age           30

因为您看到调查模式的答案列包含单词和数字,就像您认为定义 EAV 的值列一样。它不是。就像我向这个模型添加了 3 个数据类型列一样,它不会从 EAV 更改它。

我太讨厌了

有人告诉我,我正在调整的查询必须“尽可能快”。好吧,给我 10 亿美元和 30 年。“等等,十亿什么?” “尽可能”,“尽可能快”不是要求。您可以在数据库中验证您想要的任何内容...构建一个 Before 触发器的卸载,瞧!验证丰富。

年龄列的数据类型是什么?还是生日栏?取决于你的数据源是什么。一些较旧的记录可能只有月份和年份,或者只有年份,或者“大约”或“大约”某年。您不能只有一个数字列并进行“尽可能多的验证”。并且 NUMBER(2) 可能是比 NUMBER 更好的验证。所以现在你将拥有 NUMBER(1)、NUMBER(2)、NUMBER... 来拥有“尽可能多”。

我认为你被绊倒的地方

将其视为概念数据模型,而不是物理模型。在这些术语中, Survey是一个实体。Question是一个实体还是仅仅是Survey 的一个属性。如果您建立了一个表 PER,您显然是在说问题只是调查的一个属性,并且垂直存储它们使其成为 EAV。这个模型显示的是 Question 实际上是另一个实体。问题之间存在关系,例如“一个国家[可以] 编辑问题”。有原始问题并编辑了一个。每个问题都有一系列可能的答案。最重要的是,它们都是问题. 在 EAV 中,我将 fname、lname、bdate、age、major、salary 等称为完全不同的东西,只是属性。在这种情况下,我们不包括发起调查的机构名称、发布日期和到期日期等等......作为问题。

让我换一种说法。你是联邦快递。您想存储某些事件的时间戳。每次包裹进入或离开设施或车辆时。上车时间、下车到第一个设施的时间、离开那个设施到飞机上的时间等等。你是水平存放它们吗?怎么提前知道跳数?如果您将它们垂直存储,是否会自动使其成为 EAV?如果是这样,为什么。

你是一家气象公司,从全国各地的电台获取临时工。假设传感器设计为在温度变化 +/- 整度时发送读数。如果存储 sensor_ID|timestamp|temp 是阅读表,那是 EAV 吗?每个读数都不是传感器的属性,它们本身就是属于集合/系列的实体。

答案的垂直存储与 EAV 的共同点之一是难以执行分析查询。如果你想要一个所有对问题 5 和 10 回答为真但对问题 6 和 11 回答为假的人的列表,垂直完成时将非常困难。也许这就是为什么你看到这是一个 EAV。如果你想这样做,你需要一个不同的存储。问题和答案的关系存储并不是最好的报告数据库。让我们回到 Fedex 的例子。当行是垂直的时,做“运输”时间报告并不简单。

于 2011-01-07T19:11:28.383 回答
1

这听起来像是你在为一个普遍的问题苦苦挣扎:如何用锤子来拧紧螺丝。

您列出的两种选择都不好,每种都有不同的原因。但那是因为您正试图将您的特定数据模型填充到关系数据库系统中。一个好的方法是在其他一些数据库/存储系统上超越关系数据库,尝试几个,并找到最适合您的项目的方法。


我尝试过 EAV 模型并放弃了,因为它太复杂了,我不敢尝试使用关系数据库系统的多表模型。我发现的关系数据库最简单的解决方案是:将每个完整的响应存储为单个 CLOB,序列化为 JSON 或 YAML(或其他轻量级),在responses表中。

create table responses (
  id uuid primary key,
  questionnaire_id uuid references questionnaires.id,
  data text
)
于 2011-01-07T15:39:44.330 回答
1

如果我使用的是 SQL Server,Express 就可以了,那么我会这样做:

  • 带有问题列表、类型标志(位)、如果需要标志(位)、正确答案(如果存在)等的表格
  • 包含国家/地区列表的表格
  • 国家和问题的表格链接(有些国家可能没有得到一些问题
  • 包含问题列的答案表和可选问题的 xml 列,包括添加的问题

如果您不精通分解 XML,则对所有可选问题使用稀疏列。我不记得确切的表中稀疏列数的限制,但我相信它高于 30,000。SQL Server 在内部将稀疏列存储为 XML,并在选择列时将其切碎,是的,它可以被索引

下图显示了使用 SQL Server 创建的图表。列 AL_A4 将保存 QL_Id = 4 的答案,并且是稀疏类型。QuestionList 表中的 QL_Id 未标记,需要让您知道使 AnswerList 中的列稀疏。

由于国家/地区将添加问题,因此创建 QuestionListCustom、QuestiontoCountryCustom 和 AnswerListCustom 表并添加来自自定义问题的信息。

我相信还有其他设计存储的方法,这是我交作业的方式,如果这不是作业,那么你肯定为联合国工作。

替代文字

于 2011-01-07T17:24:22.163 回答
-1

你有没有考虑过不重新发明轮子?已经构建了开源调查应用程序。即使它们不能满足您的需求,也可以下载一些并查看它们的数据模型。

于 2011-01-07T15:52:17.560 回答