菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
33
0

拉链表

原创
05/13 14:22
阅读数 40555

1.定义

拉链表是一种数据库设计模,用于储存历史数据和分析时间维度的数据。

所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。

关键点:

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

拉链表一般用于解决历史版本查询的问题,也可用于解决数值区间问题,查询效率高,占用空间小。

如图是用户手机号拉链表:

开链就是第一次插入数据,这条数据没有之前的记录与之对应,只需要设定START_DATE并将END_DATE置为很久以后(比如9999年12月31日)的日期即可。

关链就是设置整条链的结尾,将END_DATE置为一个有业务意义的日期(比如三天前或一个月后都可以)即可。


2.原因

为什么要设计拉链表?

因为要追踪数据 全量快照表空间占用大,增量表虽然小,但是无法直接在一个分区内直接看到所有的轨迹数据,同时前两者无法直接查看变化时间。

用拉链表可以做到记录变化时间也做的到一条语句直接查询,最近的轨迹,还避免全分区扫描。

SELECT * FROM LINK_TABLE

 WHERE USER = 1

   AND ? >= START_DATE

   AND ? < END_DATE

 

3.使用场景案例

在数据仓库的数据模型设计过程中,经常会遇到下面这种表的设计:

  • 有一些表的数据量很大,比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。
  • 表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。
  • 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。
  • 表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。
比如现在公司的风险标表,汇率表,客户信用值表基本上都是按拉链表设计的。同时也是分区拉链表,生命周期 设置为 7天,或者为33天(因为业务逻辑)。一般可以设置成为非分区的拉链表更利于节约空间。

4.拉链表的合并与拆分

由于某些特殊的业务需要,或为了方便查询,或因为历史遗留数据,常常造成拉链表的数据太单一或拉链表的数据太多,这时可能会需要对拉链表进行合并或拆分。

1. 合并

现在有两张表:LINK_TABLE(数据为大写字母),LINK_DEMO(数据为小写字母),现在要查ID为1数据为X和y的START_DATE和END_DATE。
我要查出所有ID的所有属性组合的起止时间。

那么经过对表格的观察,我们可以画出如下的一个数轴。

最终结果应该是:

代码如下:

SELECT A.ID, A.DATA, B.DATA,
       CASE WHEN A.START_DATE<B.START_DATE THEN B.START_DATE ELSE A.START_DATE END,
       CASE WHEN A.END_DATE>B.END_DATE THEN B.END_DATE ELSE A.END_DATE END
  FROM LINK_DEMO A
  JOIN LINK_TABLE B
    ON A.ID=B.ID
   AND (A.START_DATE < B.END_DATE OR B.START_DATE < A.END_DATE);

2.拆分

拆分是合并的逆操作,就是将一个存了多个属性的拉链表拆成多个含有少量属性的拉链表。比如我们现在已经有这张LINK_COMBINE表了,我们想将它拆成LINK_DEMO和LINK_TABLE。

 

5.拉链表的生成

相关热门文章

发表评论

0/200
33 点赞
0 评论
收藏