我正在开发一个所谓的行为风险因素监测系统(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。
答案 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上,那些将是:
这种数据也有专门的数据库系统,称为多维数据库。
检查数据库是否有类似的构造或考虑切换数据库引擎
答案 2 :(得分:1)
您至少需要3张桌子:
1)Questions
,其中包含每个问题的文本,并带有自动增量ID键
例如:(123,“你头发的颜色是什么?”)
2)Questionaires
,将Q#映射到问题上。
3)Answers
,将每个回应者与他们的问卷和数据联系起来
您应该看到使用现有问题添加新问卷并添加新问题是多么容易。是的,会有巨大的表,但一个好的数据库引擎应该能够轻松处理1M条目。您可以使用分区来提高效率,例如按年分区。
我将把它留作如何将其转换为sql的练习。
答案 3 :(得分:0)
我一直在思考stackoverflow上的帖子。以下是我如何使用非规范化宽表(80+列)来支持每年更改问题以及聚合交叉制表。请评论。感谢
为每年创建一个新表,并将问题放在列上 例如
id年龄性教育收入...吸烟艾滋病饮料......
创建两个表:Question和Query_Year,一个多对多表Question_Year。然后我们可以填充指定年份可用的问题列表,反之亦然。
一年内的查询很容易。并且查询跨越多年,我们可以使用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,
我认为UNION是一个关系运算符,它不应该降低RDBMS的效率。因此,如果我通过联合组合多个表,那么它不会受到伤害。引擎还可以进行一些查询分析以提高速度。
我认为这个足够简单。请评论。谢谢!