sql - 数据仓库建模问题
问题描述
我在数据仓库中有一个典型的事实表——该表有一些代理键和度量。在数据中,仓库也是查找表——其中不维护历史的小维度。只需代理键、业务键和一两个属性。在事实表加载期间,代理键取自查找表(连接基于业务键)。所以基本上在事实加载的某个阶段,我们在事实内部有业务键,用于从查找表中获取代理键,在该操作之后,业务键就消失了,然后例如在数据集市(用于报告目的)中,我们可以加入查找事实上,仅对某些属性使用代理键。到目前为止,该过程相当简单,因为我们只使用一个业务键来设置属性值。
但是现在有些情况我们应该使用 3 甚至更多。
例如,这些是条件:
COLUMN_1 = 'ABC'
AND COLUMN_2 <> 'Z'
AND COLUMN_3 IN ('1', '2')
COLUMN_1 = 'ABC'
AND COLUMN_2 <> 'Z'
AND COLUMN_3 IN ('3', '4', '5')
COLUMN_1 <> 'ABC' OR COLUMN_2 = 'Z'
COLUMN_1、COLUMN_2、COLUMN_3 是事实表中呈现的业务键。当然,上述逻辑将应用于查找负载,因此假设我们将有 3 个代理键:1、2 和 3。
但主要问题是 - 哪种方法更适合事实表:
- 将逻辑从查找加载复制到事实加载?更好的性能,但这对维护来说更糟(如果将来需要更改,则需要在两个地方应用更改),并且代理键也需要硬编码。
- 将上述条件置于加入条件中?显然,维护会更好,但性能会更差(事实表每天插入大约 10 000 000 行)。
- 或者也许还有另一种解决方案?在源系统中结合上述条件也不是一种选择。
欢迎所有建议。
解决方案
我过去曾多次对代理键和事实负载进行建模,根据我的经验(15 年),作为良好平衡的最佳方法是以下设计:
代理键表设计 (dim_sgk) Dim_ID BR1_ID1 BR1_ID2 BR1_ID3 BRn_IDx... Record_Start_dttm
假设您有一个阶段表 (stg_tbl),您可以在其中使用业务密钥 src1.col1、src1.col2 和 src1.col3 加载源数据/文件
现在,当您从阶段表加载代理键表时,您
Select *
from
stg_tbl left outer join dim_sgk
on stg_tbl.src1.col1 = dim_sgk.br1_id1
and stg_tbl.src1.col2 = dim_sgk.br1_id2
and stg_tbl.src1.col3 = dim_sgk.br1_id3
where dim sgk.dim_id is null
并为 3 个业务密钥的所有唯一组合生成(或基于 rdbms 技术及其优缺点自动生成)代理密钥。
一次,代理键表已被刷新;您可以通过使用代理键表加入源事务表并沿途拾取代理键来开始加载您的事实(左外连接)
我已经将事实表中的业务键作为非 pk 属性保留,仅用于报告目的。无需将代理键与事实连接起来,以后只选择业务键。您可以使用代理键来优化磁盘上数据的连接和分布。但是,在将业务密钥保留为非识别属性的同时,实际上您可以两全其美。
您应该牢记代理键的多个原则(错误处理、孤儿处理等)。根据您的 rdbms 技术,基于某个索引对表进行分区可能是有意义的,这有助于您检索错误/-1 并将它们重新处理为事实表,而不会影响性能。如果您需要了解有关此技术的更多信息,请随时与我联系。乐意效劳。
我为另一个关于 SGK 的问题整理了一个非常详细的指南,您可以将其用作参考在数据仓库中管理代理键
亲切的问候,巴巴尔
推荐阅读
- iis - launchsettings.json - commandName、IIS 还是 Project for Production?
- javascript - 从父级调用子级函数说“不是函数”?
- python - 使用带有 http.client 的 api 来解析 imdb 电影数据库
- laravel - Eloquent:获取每月每一天的数据
- ffmpeg - 如何使用 MSYS2 环境为 Windows 静态编译 ffmpeg?
- c# - Selenium Firefox 不添加扩展
- c# - “新标准内核()”上的“无法加载文件或程序集 'Ninject.Web.Common'”错误
- android - 过滤recyclerview后获取位置
- ssh - 来自远程服务器的 Git 克隆在 bitbucket 管道中失败
- mysql - MySQL错误的日期计算