本文中图片引用自:https://blog.csdn.net/houfengfei668/article/details/79619215,文章中还提到了相应的全量增量图,我没有贴过来。
拉链表的定义以及适用场景
1.1定义
拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。
1.2 适用场景
给出以下一个应用场景
- 有一些表的数据量很大,比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。
- 表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。
- 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。
- 表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。
若不使用拉链表,解决方案此处给出两种:
- 方案一:每天只留最新的一份,比如我们每天抽取最新的一份全量数据到Hive中。(占无法查看历史数据)
- 方案二:每天保留一份全量的切片数据。(存储空间占用量大,无法确定数据生命周期,保留多少份全量无法控制)
此时可以考虑使用拉链表。首先它在空间上做了一个取舍,虽说不像方案一那样占用量那么小,但是它每日的增量可能只有方案二的千分之一甚至是万分之一。其次它能满足方案二所能满足的需求,既能获取最新的数据,也能添加筛选条件也获取历史的数据。
拉链表的算法
很多博客上介绍了拉链表当有更新数据时,采用的算法。本文给出一张更新过程的图与算法过程相结合,简要介绍拉链表的存储更新情况。
算法:
1、采集当日全量数据到ND(NewDay)表;
2、可从历史表中取出昨日全量数据存储到OD(OldDay)表;
3、(ND-OD)就是当日新增和变化的数据,也就是当天的增量,用W_I表示;
4、(OD-ND)为状态到此结束需要封链的数据,用W_U表示;
5、将W_I表的内容全部插入到历史表中,这些是新增记录,start_date为当天,而end_date为max值;
6、对历史表进行W_U部份的更新操作,start_date保持不变,而end_date改为当天,也就是关链操作
根据上述算法说明,下面给出操作的过程图:
注释:
- 开始结束时间表示该条记录的生命周期时间
- 结束时间为 ‘2999-12-31’表示该条记录目前处于有效状态。
- 如果查询当前所有有效的记录,则
select * from user where end_date = ‘2999-12-31’
- 如果查询2017-08-01的历史快照,则select * from user where start_date <= ‘2017-08-01’ and t_end_date >= ‘2017-08-01。\
关于hive中,数据拉链的实现,推荐一篇很好的文章:https://blog.csdn.net/zhaodedong/article/details/54177686