应用场景:
数据量大,且变化缓慢的维表,需要同时记录历史数据和最新的数据。
每天一份全量快照浪费存储空间,只保留最新的数据又无法覆盖全部业务场景,因此采用拉链表的方式进行存储。
数据变化场景:
1.当天新增
2.当天修改
3.当天删除
4.无变化
5.一天多跑
解决思路:
(使用数据生效的开始时间和结束时间来记录 数据的变化)
当天新增,直接添加新行,开始时间为当天,结束时间为极大值(9999-12-31)
当天修改,添加新行,修改旧行的结束时间为昨天
当天删除,修改结束时间
一天多跑,要和 “当天修改” 区分开来,开始时间和结束时间不变
解决方案:
- 拉链表字段设置
建立分区表dim_t_zip,
添加开始时间start_date,结束时间end_date
( 以结束时间作为分区字段,结束时间为‘9999-12-31’即为最新有效的数据,结束时间为昨天或过去的某一天,则为那一天的历史数据)
添加删除标识del_flag,区分数据 是否已在业务端被删除
- 具体步骤
- 取出拉链表中最新有效的数据放到tmp_old表中(过滤历史数据)
- 取出业务表当天更新的数据放到tmp_new表中
- 将新增的业务数据和拉链表的数据合并,tmp_old full join tmp_new ,为不同的数据变化场景打上标签,结果放到tmp_all
1:当天新增数据(tmp_old.id is null)
2:当天修改的数据(tmp_old.code !=tmp_new.code)
3:无变化的数据
4:源端已经删除的数据(tmp_new.id is null)
5:一天多跑 - 将以下1,2,3分别取出后,union all 插入到tmp_result中
- (新增数据插入,修改前的旧行 修改结束时间,源端已删除是软删除,也算是最新有效)
从tmp_all取出1,2,3,4场景的数据,如果是修改的数据,结束时间置为昨天,否则不变 - (添加修改后的数据,一天多跑场景的数据进行更新)
从tmp_all 取出2,5场景的数据,join tmp_new ,如果是5场景,开始时间和结束时间不变,如果是2场景,开始时间和结束时间分别置为当天和极大值‘9999-12-31’
- (新增数据插入,修改前的旧行 修改结束时间,源端已删除是软删除,也算是最新有效)
- 将tmp_result的数据,按照结束时间分区插到拉链表dim_t_zip中
代码实现
…