我正在尝试为医疗保健应用程序创建数据集市。数据集市中的事实基本上是与心脏相关的测量和发现,我们有100个。从1000开始,每个考试类型可以达到20000。
我想知道我对事实表的设计选择是什么:
谷物:每个检查类型每位患者1排。
我能想到的一些选择 -
1)一个包含1000或更多列的大型事实表。
2)基于EAV的设计 - 单独的度量维度表。此外键将进入事实表,度量值实际上将是表。因此,每个测量类型每个患者的事实表的粒度将变为1行。
3)根据子组等其他标准,为每种考试类型创建较小的多个事实表。但最终用户将在子组中查询该考试类型,并且不推荐事实 - 事实联接。
4)其他任何想法?
任何投入都将受到赞赏。
答案 0 :(得分:2)
<强> 1。一个包含1000或更多列的大型事实表。
如果查询直接在数据仓库中执行,则一个非常宽的事实表为最终用户提供最大灵活性。但是,应该考虑一些注意事项,因为根据平台的不同,您可能会遇到一些限制。
SQL Server 2014限制如下:
每行字节数8,060。行溢出存储可能是一种解决方案,但它只支持几种通常与事实性质无关的列类型,即varchar,nvarchar,varbinary,sql_variant。内存中OLTP也不支持。 https://technet.microsoft.com/en-us/library/ms186981(v=sql.105).aspx
每个非宽表的列1024.宽表和稀疏列是解决方案,因为每个宽表限制的列数为30,000。但是,每行的字节数限制相同。 https://technet.microsoft.com/en-us/library/cc280604(v=sql.120).aspx
每个SELECT / INSERT / UPDATE语句的列数4,096
每个表999的非聚集索引
https://technet.microsoft.com/en-us/library/ms143432(v=sql.120).aspx
<强> 2。基于EAV的设计 - 单独的度量维度表。此外键将进入事实表,度量值实际上将是表。因此,每个测量类型每个患者的事实表的粒度将变为1行。
根据Kimball的说法,EAV设计被称为 Fact Normalization 。当一些测量非常冗长时,它可能是有意义的,但对于给定的事实稀疏填充,并且没有计算在事实之间。< / p>
因为事实正常化了:
可扩展性非常简单,即无需修改数据结构即可轻松添加新测量值。
最好提取一次检查的所有测量结果,并将测量结果显示为屏幕上的行。
很难在几次测量之间提取/聚合/进行计算(例如,平均HDL与CHOL比率)并且将测量/聚合/计算呈现为列,即需要复杂的WHERE / PIVOTING或多连接。 SQL使得在不同行中的事实之间进行计算变得困难。
如果主要最终用户平台是OLAP多维数据集,则事实规范化是有意义的。立方体允许在任何维度上进行计算。
如果数据格式为平面样式CSV,则数据导入可能会出现问题。
这里也讨论了这些问题Should I use EAV model?。
3)根据子组等其他标准,为每种考试类型创建较小的多个事实表。但最终用户将在子组中查询该考试类型,不建议使用事实 - 事实加入。
在某些情况下,多个较小的事实表非常有意义。其中一个原因是,如果您达到平台设置的某些物理限制,例如每行字节数。
事实可以按主题领域分组,例如:测量组/子组,或按使用频率。每个表都可以放在一个单独的文件组中,并驱动以最大化I / O.
此外,您可以跨不同的事实表复制测量值,以减少事实表连接的需要,即将一个测量值放在特定的测量子组事实表和常用的测量事实表中。
但是,如果对数据加载有一些特定要求,则应考虑一些注意事项。例如,如果记录在您的ETL中出错到一个事实表,您可能希望确保删除其他事实表中的相应记录并将其暂存到您的错误表中,这样您就不会得到任何虚假信息。如果最终用户在前端工具中有自己的计算,则尤其如此。
如果使用OLAP多维数据集,则多个事实表实际上成为特定事实表的度量值组的来源。
就事实 - 事实连接而言,您(BI应用程序)不应该发出在事实表的外键中将两个事实表连接在一起的SQL。相反,应该使用Drilling Across两个事实表的技术,其中分别创建来自两个或多个事实表的答案集,并将结果排序合并到公共行标题属性值以产生正确的结果。
有关此主题的更多信息:http://www.kimballgroup.com/2003/04/the-soul-of-the-data-warehouse-part-two-drilling-across/
4)任何其他想法?
SQL XML或某种类型NoSQL可以是一个选项,但存在相同的查询/聚合/计算/表示问题。