拉链表学习

    作为一个刚入职场的新人,之前一直听说拉链表这个名词,一直以为是一个很高端的东西,今天闲来无事,自己学习理解了下,毕竟对自己不知道的东西应该抱有一点点好奇,哈哈~

    首先拉链表就是在数据仓库中一种存储表数据的方式,就是记录某个事物从开始一直到最后状态的变化过程。最好理解的就是银行系统中核心系统,它肯定有一张表记录所有客户的交易流水,这个表中有客户编号,核心账号,账户余额,交易日期,交易对手等等字段。每天只要发生流水,都会有记录。但是现在存在两个问题,第一,在他所有客户中,只有一部分当天发生交易。第二,在发生交易的这 一批客户中,该表中只有一部分数据发生改变,大部分数据是不变的。对于这种表,我们有三种方法可以保留数据。第一,每天保留最新的一份全量数据,然后删掉之前的数据。这样实现起来简单,节省内存,但是我们看不到历史 数据。第二,每天保留当前最新的全量数据,这样我们可以看到所有历史数据,但其实这样其实把一些不变的数据保存了很多遍,对内存是 一种很大的浪费。第三就是使用拉链表,它虽然在内存上没有第一种方法那么优秀,但是相比于第二种方法也节省了很多,同时保留了历史数据。

    拉链表原理:

   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改为当天

   其中,5,6步不太好理解,当时我自己绕了很久。其实想一下,它就是在历史表中,能看到每个时间段发生变化的过程。比如一张用户表,第一天20180101有A,B,C三个 用户,账户余额分别是10000,40000,30000。第二天20180102,这个表有四个用户A,B,C,D,金额分别是10000,50000,26000,200。其实和第一天相比,D用户是新增的,B和C的值发生了改变,A没有任何变化。那么,对应到上面如下:

OD(OldDay)表:

用户账户余额stat_dtent_dt
A100002018010199991231
B400002018010199991231
C300002018010199991231

ND(NewDay)表:

用户 账户余额stat_dtend_dt
A100002018010299991231
B500002018010299991231
C260002018010299991231
D2002018010299991231

W_I=ND-OD(这些是新增数据,需要插入历史表 ,然后 把stat_dt改为当前日期,end_dt改为 最大值)

用户账户余额stat_dtend_dt
B500002018010299991231
C260002018010299991231
D2002018010299991231

W_U=OD-ND(这些是从20180101到20180102需要封存的数据,在历史表修改,把end_dt改为 当前日期)

用户账户余额stat_dtend_dt
B400002018010199991231
C300002018010199991231

提示:重要的两步

insert操作把W_I插入历史表

用户账户余额stat_dtend_dt
A100002018010199991231
B400002018010199991231
C300002018010199991231
B500002018010299991231   --NEW
C260002018010299991231   --NEW
D2002018010299991231   --NEW

update操作在历史表修改W_U

用户账户余额stat_dtend_dt
A100002018010199991231
B400002018010120180102   --UPDATE
C300002018010120180102   --UPDATE
B500002018010299991231
C260002018010299991231
D2002018010299991231

    最后就成了这样,其实总的来说,就是有一个全量的历史表,我们拿到今天 数据和昨天的 对比,拿到发生改变字段的增量数据,在历史表中逐条插入这一部分增量数据(上面的B,C,D),stat_dt为当前,end_dt为最大值。然后再在历史表中,修改这部分增量数据对应的昨天的记录(上面的B,C),保持stat_dt不变,把end_dt改为当前。这样,我们就能清楚的看到每个对象从产生到最后的 变化状态。

    end_dt为有效的数据,如果查当前所有有效的数据:select * from user  where end_dt=‘99991231’。(作为初学者,我当时不知道为啥end_dt为‘99991231’为有效的状态。其实想一下,end_dt为‘99991231’就是说它从产生到现在一直没有改变过,或者说某次改变后再 没有变化过,所以是当前有效 的状态)。如果需要查看20180102这一天的数据,则select * from user where  stat_dt<='20180102' and end_dt>='20180102’(作为初学者,我当时一直在想,要查20180102的数据,让stat_dt为啥有stat_dt<20180102和ent_dt>20180102这部分,后来想一下,因为比如20180101这天产生的一天记录,到20180102这天状态没有改变,那么这条数据在20180102是存在的,但是stat_dt是20180101,所以会有stat_dt<20180102。同时,如果一个数据在20180102这天后者这天之前改变的,那么这些数据在20180102这天存在,但是end_dt是99991231,所以会有end_dt>20181231这部分)。





  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值