客观的
假设您在 ETL 的帮助下构建数据湖和星型模式。存储格式为 Delta Lake。ETL 的职责之一是构建渐变维度 (SCD) 表(累积状态)。这意味着对于每个 SCD 表,ETL 每天都会读取整个表的状态,应用更新并将它们保存回来(完全覆盖)。
问题
我们团队内部争论的一个问题:我们应该将时间分区添加到 SCD(完全覆盖)表吗?意思是,我应该将最新的(完整)表状态保存到SOME_DIMENSION/
还是保存到SOME_DIMENSION/YEAR=2020/MONTH=12/DAY=04/
?
注意事项
一方面,Delta Lake 具有所有必需的功能:时间旅行和 ACID。当它覆盖整个表时,会发生逻辑删除,您仍然可以查询旧版本并回滚到它们。所以 Delta Lake 几乎为你管理时间分区,代码变得更简单。
另一方面,我说“几乎”是因为恕我直言时间旅行和酸不能覆盖 100% 的用例。它没有到达时间的概念。例如:
示例(当您需要时间分区时)
BA团队报告SOME_FACT/YEAR=2019/MONTH=07/DAY=15
数据被破坏(事实必须以时间分区存储,因为数据是按到达时间处理的)。为了在 DEV/TEST 环境中重现问题,您需要 1 个事实表原始输入和 10 个 SCD 表。
有了事实,一切都很简单,因为您在 Data Lake 中有原始输入。但是对于增量状态(SCD 表),事情变得复杂 -如何在SOME_FACT/YEAR=2019/MONTH=07/DAY=15
处理的时间点获取 10 个 SCD 表的状态?如何自动执行此操作?
更复杂的是,您的环境可能会出现大量错误修复和历史重新处理。意味着 2019-07 数据可能会在 2020 年的某个地方重新处理。Delta Lake 允许您仅根据处理或版本号进行回滚。所以你实际上不知道你应该使用哪个版本。
另一方面,使用日期分区,您始终可以确定SOME_FACT/YEAR=2019/MONTH=07/DAY=15
是在SOME_DIMENSION/YEAR=2019/MONTH=07/DAY=15
.