调查查询系统的数据库设计

时间:2009-02-25 07:04:34

标签: python database django sqlite

我正在开发一个所谓的行为风险因素监测系统(BRFSS),这是一个处理每年调查问卷的网络查询系统。

我很难为它提出合适的数据库设计。问题在于:每个调查问卷包含大约80个问题,其中包含人口统计信息,例如:年龄,教育等,以及调查问题,例如吸烟,健康等。每年,一些问题都会改变,有些则不会改变。数据源是一个包含80多列的Excel文件。系统必须支持以下查询:

SELECT [question var], [demo var], count(*) 
FROM survey 
WHERE age in (...) AND educ in (...) [etc] 
GROUP BY <question var>

数据是只读的,即。导入后永远不会改变。所以它不必太过标准化。直观地说,类似电子表格的表格可以很好地完成。速度和空间。然而,这成为一个问题,因为问题会发生变化,然后我们无法将所有数据保留在此表中,这是因为跨年查询所必需的。

我尝试将响应规范化为三个表:问题,响应和response_values,它们可以支持问题变体。但是响应表一年超过98 * 14268 = 1,398,264行!这真的很大。查询很疯狂!

我应该如何设计数据库?任何帮助表示赞赏!提前谢谢!

PS。我使用的是Python + Django + Sqlite。

4 个答案:

答案 0 :(得分:6)

您是否检查了DatabaseAnswers以查看是否有可用作起点的架构?

答案 1 :(得分:1)

听起来像星型模式的情况。

你会有一个(巨大的)事实表:

question_id,survey_id,age_group_id,health_classifier_id,is_smoking ...,answer_value

和非规范化维度表:

AGE_GROUP: group_name,min_age,max_age,age_group_id

对于这样的系统来说,140万行听起来并不多。

某些数据库具有支持查询此类架构的特殊功能:

在Oracle上,那些将是:

  • '维度'用于支持加重所有维度
  • 用于过滤低基数属性(如age_group_id和is_smoking
  • )的位图索引
  • 位图连接索引,用于过滤连接表中的低基数属性,即从事实表中选择,但过滤age_group表中的min_age。
  • 分区表以处理大型表格
  • 预先计算聚合结果的物化视图

这种数据也有专门的数据库系统,称为多维数据库。

检查数据库是否有类似的构造或考虑切换数据库引擎

答案 2 :(得分:1)

您至少需要3张桌子:

1)Questions,其中包含每个问题的文本,并带有自动增量ID键

例如:(123,“你头发的颜色是什么?”)

2)Questionaires,将Q#映射到问题上。

例如,关于问卷#3的问题#10映射到问题#123。

3)Answers,将每个回应者与他们的问卷和数据联系起来

例如,鲍勃对问卷#3问题#10的回答是“棕色”。

您应该看到使用现有问题添加新问卷并添加新问题是多么容易。是的,会有巨大的表,但一个好的数据库引擎应该能够轻松处理1M条目。您可以使用分区来提高效率,例如按年分区。

我将把它留作如何将其转换为sql的练习。

答案 3 :(得分:0)

我一直在思考stackoverflow上的帖子。以下是我如何使用非规范化宽表(80+列)来支持每年更改问题以及聚合交叉制表。请评论。感谢

  1. 为每年创建一个新表,并将问题放在列上 例如

    id年龄性教育收入...吸烟艾滋病饮料......

  2. 创建两个表:Question和Query_Year,一个多对多表Question_Year。然后我们可以填充指定年份可用的问题列表,反之亦然。

  3. 一年内的查询很容易。并且查询跨越多年,我们可以使用UNION运算符。由于问题应在所选年份之间兼容,因此UNION是合法的。 例如

    SELECT * FROM(     SELECT id ,,, COUNT()FROM survey_2001     UNION ALL     SELECT id ,,, COUNT()FROM survey_2003     UNION ALL     SELECT id ,,, COUNT(*)FROM survey_2004     UNION ALL     等等 ) 在哪里(     AGE in(...)AND     (......)AND中的EDUC     等等 ) GROUP BY,

  4. 我认为UNION是一个关系运算符,它不应该降低RDBMS的效率。因此,如果我通过联合组合多个表,那么它不会受到伤害。引擎还可以进行一些查询分析以提高速度。

    我认为这个足够简单。请评论。谢谢!