用于存储调查答案的数据库模式

时间:2016-06-20 01:53:20

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

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

我没有经验,所以我想征求意见:

  1. 用于存储用户答案的​​数据库架构,我担心我目前的设计可能存在性能问题......
  2. 关于调查:

    1. 同时会有两项或多项调查。
    2. 调查可能每年触发一次或更频繁,所以我认为我需要一份调查期表。
    3. 调查针对不同的产品,因此产品和调查之间会有映射
    4. 目前我的设计:

      调查类别表

      +------------+--------------+
      | 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列。

1 个答案:

答案 0 :(得分:0)

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

每年3000万行,特别是在这些瘦表中,是任何Oracle系统的少量数据。不要过多担心索引和分区,如果有必要,可以在以后添加。

您的解决方案类似于实体属性值(EAV)模型。值得知道这个词,因为它已经写了很多。您希望避免使用EAV模型的两个常见问题:

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

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