【发布时间】:2022-01-12 10:32:25
【问题描述】:
假设我们有一个由四个组件组成的数据仓库:
- extract :源数据从 oracle 数据库中提取到平面文件中。每个源表都有一个平面文件。提取日期保留为平面文件名的一部分。每条记录都包含来自源系统的插入/更新日期。
- 暂存区:用于将提取的数据加载到数据库表中的临时表
- 运营数据存储:暂存数据将加载到 ODS。 ODS 保留所有加载数据的所有历史记录,并且数据是类型转换的。尚未生成代理键。
- datawarehouse :从 ODS 加载数据,生成代理键,对维度进行历史记录,最后加载事实数据并将其附加到适当的维度。
到目前为止一切顺利,关于常规增量加载,我没有问题。但是我问自己的问题是:我在过去经常遇到的情况是,无论出于何种原因,您都希望将提取的数据重新提交到加载管道中。例如,假设我们选择了过去 15 天内提取的所有平面文件,并将它们再次推送到 ETL 流程。
- 没有从源系统中提取新内容。之前加载的文件会被重新使用并送入 ETL 流程。
- 然后将数据重新加载到之前已被截断的暂存表中
- 现在数据必须移动到 ODS。在这里,我真的很头疼如何进行。
备选方案 1 :只需插入新行。所以我们会有: 第 2 行,自然键:ID001,批处理日期:12/1/2022 16:34,提取日期:10/1/2022,源系统修改时间戳:10/1/2022 10:43:00 上一行:自然键:ID001,批处理日期:10/1/2022 01:00,提取日期:10/1/2022,源系统修改时间戳:10/1/2022
但是,当加载到 DWH 时,我们需要某种插入/更新机制,我们不能直接插入,因为它会创建重复的事实。
备选方案 2:在 ODS 级别应用插入/更新逻辑。对于前面的示例,我们将有:
- 检查 ODS 表是否已经包含带有自然键的行:ID001 - 提取日期:2022 年 10 月 1 日,源系统修改时间戳:2022 年 10 月 1 日
- 如果找不到则插入
备选方案3:在ODS中清除之前加载的数据,即
- 清除提取日期在过去 15 天内的所有数据
- 从暂存区加载数据。
替代方案 1 是高性能的,但将插入/更新任务转移到 DWH 级别,因此性能杀手仍然存在。 备选方案 2 需要插入更新,这对于数百万行似乎不是最优的。 备选方案 3 看起来不错,但如果从 ODS 中删除数据感觉不对。
您对此有何看法?换句话说,我的问题是如何协调在数据仓库中具有仅插入进程的建议与现实情况,即您需要不时重新加载先前提取的数据以修复错误或纠正丢失的数据。
【问题讨论】:
-
独立于架构的级别,DWH 中通常有两种类型的流:full 和 delta 负载。在 full 刷新的流(例如较小的维度)中重复加载不会出现 no 问题,因为您之前总是重置目标表。在 delta 加载(例如事实表)中,您必须删除您在第一步中重新加载的数据。这通常由标识要删除的数据的审计维度支持。
-
通常,ODS 是源的副本,因此无论如何您都应该始终在 ODS 层进行合并。即使有数百万行,这就是您所做的。但是,这取决于您重新运行集成的理由。您的数据集成是“幂等的”也是一个基本要求,也就是说,如果您意外或故意重新运行事物,则不应出现重复。
-
我同意你的观点,合并似乎很简单;我只是对我在其他地方看到的建议有一个智力问题,即理想情况下,您的数据仓库应该完全基于插入,没有更新。对我来说,合并意味着进行插入/更新。但也许不建议做的是逐行更新,基于集合的更新是可以的?
-
理想情况下,您的数据仓库应该完全基于插入这听起来像是一个 Data Vault 的想法。 Data Vault 绝对不是数据仓库。这是一个摄取/存储模型(如果你问我,它是一个过于复杂的模型)。很少有理由在数据库中逐行更新(即基于游标)
标签: etl data-warehouse