http://www.alidw.com/?p=641
谈下ETL过程中经常遇到的历史拉链表的做法,假定现在的目标表是t,增量表是s,现在要把S表的数据加载到历史拉链表T中,
不要使用update语句,常见的实现方案有如下几种,具体实现步骤可参见下方。
方法一:
1)用t表与s表进行关联比较,把t表中已经改变的记录选择出来,更新结束日期为当前etl日期,然后把结果加载到临时表tmp1
2)delete t表中已经发生改变的那些记录
3)把tmp1表中的记录以及s表的记录都加载到t中,注意,s表在加载要t表时,开始日期是当前etl日期,结果日期为最大日期
方法二:
1)用t表与s表进行关联比较,把t表中已经改变的记录选择出来,更新结束日期为当前etl日期,然后把结果加载到临时表tmp1
2)用t表与s表进行关联比较,把t表中没有改变的记录选择出来,然后加载到临时表tmp1中
2)truncate t表
3)把tmp1表中的记录以及s表的记录都加载到t中,注意,s表在加载要t表时,开始日期是当前etl日期,结果日期为最大日期
方法二:
1)用t表与s表进行关联比较,把t表中已经改变的记录选择出来,更新结束日期为当前etl日期,然后把结果加载到临时表tmp1
2)用t表与s表进行关联比较,把t表中没有改变的记录选择出来,然后加载到临时表tmp1中
2)把s表的记录都加载到t中,注意,s表在加载要t表时,开始日期是当前etl日期,结果日期为最大日期
3)然后将temp表与t表交换表名
看了上述方法,肯定会有人说如果表很大,那时候怎么去比较,其实方法很简单,如果你的目标表t中只有少量几个数值型的字段改变
才需要记录历史,那么你完全在关联后,通过比较t表与s表的相应字段不相等来判断;如果你的目标表t中是大量字段或者是字符型的字段
改变就需要记录历史,那么你可以考虑使用hash比较,就是计算出每行记录的hash值,然后使用hash值比较。
看完上述那些,有人肯定认为一个历史拉链表就做完了,其实不考虑异常处理以及记录日志要素,这个历史拉链表确实做完,但是实际
上这个脚本是不健壮的,为什么呢?因为它不知道回滚。因为你需要在做历史之前增加一次判断,如果本次etl过程是需要回滚的,那么就
需要执行回滚操作,历史拉链表的回滚操作就是要根据回滚的日期把目标表中开始日期大于等于回滚日期的记录全部删除,同时还要把目标表
中结束日期为回滚日期的记录的结束日期更新为最大日期,至于这些操作如果实现最有效率,可以参见我之前的文章ETL随笔(一)。