拉链表是数据仓库中一种重要的模型,相信很多数据工作者都接触过,面试也是经常考察的点。
但是很多人第一次接触“拉链表”这个词,难免会产生疑惑:拉链表是什么?
目录
什么是拉链表
按照度娘的解释:“拉链表是一种针对数据仓库设计中表存储数据的方式而定义的数据模型,它有点类似于快照,用于维护历史状态及最新状态数据。”
这么看还是有点难理解,既然如此,那我们先不管,先来看以下场景:
- 假如有张表如表1-1所示,每天的数据量大概有50w
- 表中有些字段会被 update,如表1-2,且每天更新的数据量很小,大约只有5k
- 有些报表需要查看历史某个日期的数据
- 存储空间有限,需要尽可能的节约存储空间
问:你会怎么将其装入数仓中?
表1-1:
idnamephone1Agnes1232Max4563Tony789………
表1-2:
idnamephone1Agnes1232Max4563Tony321………
每天追加一份全量数据
这种方式比较简单粗暴,如表1-3,不仅操作方便,还可以反映历史变化。但是弊端也很明显:存在数据冗余、浪费存储空间。
每天50w,一个月就有1500w了,时间越长,数据量越多,然而实际变化的数据每天只有5k,剩下的数据几乎都是重复存储的,极大浪费存储空间。
表1-3
idnamephone1Agnes1232Max4563Tony7891Agnes1232Max4563Tony321………
直接覆盖原来的数据
这种方式也很简单,直接全表 truncate 再 insert,虽然空间节省了,但缺点也很明显,会把历史数据覆盖掉,没办法反映历史数据的变化。
使用拉链表
在原表结构的基础上,加两个字段:start_date 和 end_date,第一次抽取数据的时候,将 start_date 初始化为抽取日期,end_date 初始化为永久日期,如表1-4所示
表1-4:
idnamephonestart_dateend_date1Agnes12320230328999999992Max45620230328999999993Tony7892023032899999999……………
之后的每一次抽取,则需要对比当日数据以及历史数据,将有变化的历史数据的 end_date 改成当日抽取日期;
将新抽取的有变化的数据按照初始化的方式设置 start_date 和 end_date。如表1-5所示
表1-5:
idnamephonestart_dateend_date1Agnes12320230328999999992Max45620230328999999993Tony78920230328202303293Tony3212023032999999999……………
这种数据模型就是拉链表,它既能反映历史变化,又能节省空间,岂不美哉?
如何实现拉链表
既然理解了什么是拉链表,那么应该如何实现呢?
方式一
(1)获取当日数据;
(2)比较当日数据及历史数据,找出新增和变化的数据,存到临时表,并将开始日期置为当前日期,结束日期置为最大日期;
(3)将历史数据表中的变化数据的结束日期更新为当前日期,即闭链;
(4)将临时表的新增和变化数据插入历史数据表中,即开链。
方式二
(1)获取当日数据;
(2)比较当日数据和昨日数据,找出新增数据和变化后数据;
(3)比较昨日数据和当日数据,找出删除数据和变化前数据;
(4)删除历史数据表中的删除数据和变化前数据;
(5)将新增数据和变化后数据插入历史数据表中,把开始日期置为当前日期,结束日期置为最大日期;
(6)将删除数据和变化前数据插入历史数据表中,把结束日期置为当前日期。
方式一比较简洁;在数据量比较大的情况下,方式二效率比较高,因为用删除插入的操作替代更新的操作,当然,这是对于传统数据库而言,具体的方式应根据实际数据量和数据库来制定。
小结
本文用一个案例简单介绍了拉链表的含义以及实现拉链表的方式,如果有什么错误,欢迎大家指正;如果对大家有帮助,希望大家能给个赞给予肯定支持,谢谢。
持续关注不迷路,转载请注明出处:大数据的奇妙冒险
版权归原作者 大数据的奇妙冒险 所有, 如有侵权,请联系我们删除。