【问题标题】:What database schema to use for storing survey answers用于存储调查答案的数据库架构
【发布时间】:2016-06-23 10:42:45
【问题描述】:

我需要为我们的客户设计一个调查系统。 它基于asp.net,使用的数据库是oracle

我在这里没有经验,所以我想就以下方面寻求建议:

  1. 使用什么数据库架构来存储用户答案,恐怕我目前的设计可能存在性能问题...

关于调查:

  1. 将同时进行两项或多项调查。
  2. 调查可能每年触发一次或更频繁,因此我认为我需要一个调查周期表。
  3. 调查针对不同的产品,因此产品和调查之间会有映射

目前我的设计:

调查类别表

+------------+--------------+
| CatageryId | CatageryName |
+------------+--------------+
|          1 | cat1         |
|          2 | cat2         |
+------------+--------------+

调查类别版本表

+-----------+------------+--------------------+
| VersionId | CatageryId | VersionDescription |
+-----------+------------+--------------------+
|         1 |          1 | 'cat1 version1'    |
|         2 |          1 | 'cat1 version2'    |
|         3 |          2 | 'cat2 version1'    |
+-----------+------------+--------------------+

调查周期表

+----------+--------------------+
| PeriodId | PeriodDescription  |
+----------+--------------------+
|        1 |  'cat1 period2016' |
|        2 |  'cat1 period2017' |
|        3 |  'cat2 period2016' |
+----------+--------------------+

调查周期-版本对照表

+----------+-----------+
| PeriodId | VersionId |
+----------+-----------+
|        1 |         1 |
|        1 |         2 |
|        2 |         1 |
|        3 |         3 |
+----------+-----------+

版本-问题映射表

+--------------+------------+
| VersionId |  | QuestionId |
+--------------+------------+
|            1 |          1 |
|            1 |          2 |
|            1 |          3 |
|            2 |          1 |
|            2 |          2 |
|            3 |          1 |
+--------------+------------+

版本-产品映射表

+-----------+-----------+
| VersionId | ProductId |
+-----------+-----------+
|         1 | 'prodA'   |
|         1 | 'prodB'   |
|         1 | 'prodC'   |
|         2 | 'prodA'   |
+-----------+-----------+

为了存储调查结果数据,我必须在记录行之间放置大量重复信息:

用户答案表 +----------+------------+----------+-----------+-----------+--------+-----------+ | AnswerId | QuestionId | PeriodId | UserId/Ip | ProductId | Answer | VersionId | +----------+------------+----------+-----------+-----------+--------+-----------+ | 1 | 1 | 1 | 'adam' | 'prodA' | 'Yes' | 2 | | 2 | 2 | 1 | 'Joe' | 'prodA' | 'Yes' | 2 | | 3 | 1 | 2 | 'adam' | 'prodB' | 'A' | 3 | +----------+------------+----------+-----------+-----------+--------+-----------+ 我们期待这个系统有数十种产品和数千名用户。 所以假设有 30 种产品,5000 名用户,每次调查 50 个问题,每年进行 4 次调查

在当前设计中,每年将有 5000 * 4 * 50 * 30 = 3000 万条记录添加到用户答案表中, 我真的很害怕它是否仍然可以正常工作......那么有什么优化建议吗?

编辑 1: 按照建议在用户答案表中添加 VersionId 列。

【问题讨论】:

  • 您的 Answer 表中没有 VersionId。你怎么知道这个答案属于哪个调查版本?您建议的卷可以由 Oracle 数据库管理。您可以计划根据 PeriodId 在答案表中实施分区。
  • @phonetic_man ,是的,你是对的,我会编辑添加一列...我还会找到有关分区的更多信息,非常感谢。
  • @phonetic_man,非常感谢您的帮助。读完这篇文章后,我想我会在 PeriodId 列上进行列表分区。希望不会有问题,因为我认为当前的数据库设计有点过于复杂......

标签: asp.net database oracle database-design schema


【解决方案1】:

这看起来像是过早优化的情况。您可能应该更多地担心正确性和灵活性而不是性能。

每年 3000 万行,尤其是在这些瘦表中,对于任何 Oracle 系统来说都是少量数据。不要太担心索引和分区,如果需要,可以稍后添加。

您的解决方案类似于实体属性值 (EAV) 模型。了解这个术语是值得的,因为关于它的文章很多。您需要避免 EAV 模型的 2 个常见问题:

  1. 避免极端。不要将 EAV 用于一切,但也不要完全避免它。与普通的表结构相比,EAV 既慢又不方便。它不应该用于每个有趣的列,否则您已经在数据库中创建了一个数据库。例如,如果几乎每个调查都有用户名和创建日期等字段,则将它们存储为常规列而不是通用列。有一个只有 99% 的时间填充的列是可以的。另一方面,总是避免使用 EAV 并尝试使用 1,000 个列表或对象关系类型来破解某些东西是个坏主意。

  2. 始终使用正确的类型。始终、始终、始终将数据存储为正确的类型。将数字存储为数字,将日期存储为日期,将字符串存储为字符串。如果您的数据至少有三列:ANSWER_NUMBER、ANSWER_STRING、ANSWER_DATE,您的查询将更容易、更快、更安全。我在this answer 中更多地解释了类型安全问题。这些额外的列在模型图中可能看起来很糟糕,但在您查询数据时它们是救命稻草。

【讨论】:

  • 接受30 million rows per year, especially ...。作为这里的新手,这是我最关心的..
  • 很遗憾我的时间如此有限,以至于我不得不在上周完成程序的主要架构。我仍然使用我原来的桌子设计,但我会更多地了解 EAV 模型。顺便说一句,我认为调查结果表类似于 EAV 表不是吗... xxxIDs 字段之类的属性...感谢您对use correct types 的建议,我之前没有想到要使用不同的类型用于存储变量值。
猜你喜欢
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
相关资源
最近更新 更多