拉链表

  拉链表是针对数据仓库设计中表存储数据的方式而定义的。拉链,就是记录历史,一个事物从开始,一直到当前状态的所有变化的信息。

简介

关键点:

  • 储存开始时间和结束时间。
  • 开始时间和结束时间首尾相接,形成链式结构。

  拉链表与LinkedList很相似,都以快速找到下一个元素为设计目标,只不过链表会存储内存地址,而拉链表只存了下一条数据的开始时间。理论上如果存了下一条数据的id也是可以的。
  拉链表一般用于解决历史版本查询的问题,也可用于解决数值区间问题,查询效率高,占用空间小。

适用场景

  • 数据量比较大。
  • 表中的部分字段会被更新,如用户的地址,产品的描述信息,订单的状态等。
  • 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态,更新次数等。
  • 变化的比例和频率不是很大,比如,总共有1000万的会员,每天新增和发生变化的有10万左右;如果对这边表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极大的浪费。

操作

  开链:就是第一次插入数据,这条数据没有之前的记录与之对应,只需要设定START_DATE并将END_DATE置为很久以后(比如9999年12月31日)的日期即可。
  关链:就是设置整条链的结尾,将END_DATE置为一个有业务意义的日期(比如三天前或一个月后都可以)即可。

算法

  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改为当天,也就是关链操作。

应用

  以天为维度,以每天的最后一个状态为当天的最终状态。
  以一张订单表为例,如下是原始数据,每天的订单状态明细
  1 2016-08-20 2016-08-20 创建
  2 2016-08-20 2016-08-20 创建
  3 2016-08-20 2016-08-20 创建
  1 2016-08-20 2016-08-21 支付
  2 2016-08-20 2016-08-21 完成
  4 2016-08-21 2016-08-21 创建
  1 2016-08-20 2016-08-22 完成
  3 2016-08-20 2016-08-22 支付
  4 2016-08-21 2016-08-22 支付
  5 2016-08-22 2016-08-22 创建

根据拉链表得到

  1 2016-08-20 2016-08-21 支付 2016-08-21 2016-08-21
  1 2016-08-20 2016-08-22 完成 2016-08-22 9999-12-31
  2 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-20
  2 2016-08-20 2016-08-21 完成 2016-08-21 9999-12-31
  3 2016-08-20 2016-08-20 创建 2016-08-20 2016-08-21
  3 2016-08-20 2016-08-22 支付 2016-08-22 9999-12-31
  4 2016-08-21 2016-08-21 创建 2016-08-21 2016-08-21
  4 2016-08-21 2016-08-22 支付 2016-08-22 9999-12-31
  5 2016-08-22 2016-08-22 创建 2016-08-22 9999-12-31
  可以看出 1,2,3,4 每个订单的状态都有,并且也能统计到当前的有效状态。