大数据-拉链表模型
拉链表是一种维护历史状态,以及最新状态数据的一种表。拉链表根据拉链粒度的不同,去除了一部分不变的记录,通过拉链表可以很方便的还原出拉链时点的客户记录,实际上相当于快照。
拉链表特征
1)记录一个事物从开始,一直到当前状态的所有变化的信息;
2)每次上报的都是历史记录的最终状态,是记录在当前时刻的历史总量;
3)当前记录存的是当前时间之前的所有历史记录的最后变化量(总量);
4)存量一般设计成拉链表(月报 - 常用、日报);
5)关链时间可以是3000年,9999等比较大的年份,例如[2022-07-01,9999-12-31]
表示连续的状态,因为开始时间为2022-07-01,闭合时间为未知;
拉链表适用场景
1) 数据量比较大。
2) 表中的部分字段会被更新,比如用户的地址,银行利率,订单的状态等。
3) 需要查看某一个时间点或者时间段的历史快照信息,比如,查看利率在历史某一个时间点的状态。
4) 变化的比例和频率不是很大,比如,总共有1000万的会员,每天新增和发生变化的有10万左右。
5) 如果对这边表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极大的浪费;
拉链历史表,既能满足反应数据的历史状态,又可以最大程度的节省存储。
举个栗子:
- 假如有张表如表1-1所示,每天的数据量大概有50w
- 表中有些字段会被 update,如表1-2,且每天更新的数据量很小,大约只有5k
- 有些报表需要查看历史某个日期的数据
- 存储空间有限,需要尽可能的节约存储空间
表1-1
id | name | phone |
---|---|---|
1 | Agnes | 123 |
2 | Max | 456 |
3 | Tony | 789 |
表1-2
id | name | phone |
---|---|---|
1 | Agnes | 123 |
2 | Max | 456 |
3 | Tony | 321 |
方法1:每天追加一份全量数据
这样可以根据日期查看历史的数据,但是没有改变的数据会产生数据产生大量冗余,浪费存储空间,时间一长会非常浪费。
方法2:直接覆盖原数据
这样存储空间虽然节省了,但是历史数据会被覆盖,没有办法反应历史数据的变化
方法3:使用拉链表
在原始表的基础上,增加start_datte和end_date,第一次抽取的时候,将start_date初始化为抽取日期,end_date初始化为永久日期,形成一个开区间[20231018,99999)
id | name | phone | start_date | end_date |
---|---|---|---|---|
1 | Agnes | 123 | 20231018 | 99999999 |
2 | Max | 456 | 20231018 | 99999999 |
3 | Tony | 789 | 20231018 | 99999999 |
之后抽取的时候,将end_date改为当前抽取的日期,形成两个区间:[20231018,20231019]和[20231019,99999999)
id | name | phone | start_date | end_date |
---|---|---|---|---|
1 | Agnes | 123 | 20231018 | 99999999 |
2 | Max | 456 | 20231018 | 99999999 |
3 | Tony | 789 | 20231018 | 20231018 |
3 | Tony | 321 | 20231019 | 99999999 |
拉链表如何实现
方法一:
(1)获取当日数据;
(2)比较当日数据及历史数据,找出新增和变化的数据,存到临时表,并将开始日期置为当前日期,结束日期置为最大日期;
(3)将历史数据表中的变化数据的结束日期更新为当前日期,即闭链;
(4)将临时表的新增和变化数据插入历史数据表中,即开链。
方法二:
(1)获取当日数据;
(2)比较当日数据和昨日数据,找出新增数据和变化后数据;
(3)比较昨日数据和当日数据,找出删除数据和变化前数据;
(4)删除历史数据表中的删除数据和变化前数据;
(5)将新增数据和变化后数据插入历史数据表中,把开始日期置为当前日期,结束日期置为最大日期;
(6)将删除数据和变化前数据插入历史数据表中,把结束日期置为当前日期。
方式一比较简洁;在数据量比较大的情况下,方式二效率比较高,因为用删除插入的操作替代更新的操作,当然,这是对于传统数据库而言,具体的方式应根据实际数据量和数据库来制定。
https://blog.csdn.net/weixin_43596734/article/details/129855284