Hive之拉链表

Hive有很多种表种类
内部表,外部表,分区表,桶表
全量表、增量表、快照表、切片表和拉链表

  1. 存量、流量、增量
    存量:系统在某一时间点所存有的全部数据量;
    流量:是指在某一段时间内流入/出系统的数量;
    增量:是指在某一段时间内系统中保有数量的变化;
    增量=流入量—流出量
    本期期末存量=上期期末存量+本期内增量;

五、拉链表

拉链表专门为了解决在数据仓库中数据变化如何实现数据存储问题,顾名思义,所谓 拉链,就是记录历史。记录 一个事物从开始,一直到当前状态的所有历史变化的信息。

需要条件:
1、需要一张ODS层的用户全量表,需要用它来初始化
2、每日的用户更新表

实现步骤:1、采集增量数据到增量表中

      2、将增量表和历史拉链表数据合并,结果写到临时表中

      3、将临时表数据覆盖到拉链表中

每日的用户更新表该怎么获取,有以下方式拿到或者间接拿到每日的用户增量:
可以监听Mysql数据的变化,比如说用Canal,最后合并每日的变化,获取到最后的一个状态
假设每天都会获得一份切片数据,可以通过取两天切片数据的不同来作为每日更新表,这种情况下可以对所有的字段先进行concat,再取md5
流水表,有每日的变更流水表
通过etl工具对操作型数据库按照时间字段增量抽取到ods或者数据仓库(每天抽取前一天的数据),形成每天的增量数据(实际中使用最多的情形)。

总结:
1、使用拉链表的时候可以不加t_end_date,即失效日期,但是加上之后,能优化很多查询
2、可以加上当前行状态标识,能快速定位到当前状态
3、在拉链表的设计中可以加一些内容,因为每天保存一个状态,如果在这个状态里面加一个字段,比如如当天修改次数,那么拉链表的作用就会更大

-- 先存临时表,再覆盖
INSERT OVERWRITE TABLE dws.user_his_tmp
SELECT * FROM 
( 
    SELECT A.user_num, 
           A.mobile, 
           A.reg_date, 
           A.t_start_time, 
           CASE 
                WHEN A.t_end_time = '9999-12-31' AND B.user_num IS NOT NULL THEN '2017-01-01'   -- 原拉链最新数据有更新,更改t_end_time
                ELSE A.t_end_time 
           END AS t_end_time 
    FROM dws.user_his AS A  -- 拉链表
    LEFT JOIN ods.user_update AS B -- 今日新增/更新数据
    ON A.user_num = B.user_num 
    
UNION 
    SELECT C.user_num, 
           C.mobile, 
           C.reg_date, 
           '2017-01-02' AS t_start_time, 
           '9999-12-31' AS t_end_time 
    FROM ods.user_update AS C -- 今日新增/更新数据
) AS T 

拉链表和流水表
流水表存放的是一个用户的变更记录,比如在一张流水表中,一天的数据中,会存放一个用户的每条修改记录,但是在拉链表中只有一条记录。
这是拉链表设计时需要注意的一个粒度问题。我们当然也可以设置的粒度更小一些,一般按天就足够。

查询性能
拉链表当然也会遇到查询性能的问题,比如说我们存放了5年的拉链数据,那么这张表势必会比较大,当查询的时候性能就比较低了,个人认为两个思路来解决:
在一些查询引擎中,我们对 start_date 和 end_date 做索引,这样能提高不少性能。这种方法其实在 Hive 中行不通,因为 Hive 相当于没有索引,不过在其它系统中可以考虑。
保留部分历史数据,比如说我们一张表里面存放全量的拉链表数据,然后再对外暴露一张只提供近 3 个月数据的拉链表。

淘汰机制
关于淘汰机制,其实和性能也是有关系的,一方面是因为所有数据的积累会导致计算越来越慢,另一方面是业务侧其实对历史数据的需求也有一定的优先级的。
因此在设计拉链表的时候可以制定一些数据的淘汰机制。淘汰的数据不一定要删除,比如我们建立两张拉链表,一张拉链表中只保存最新的十条数据,其它的数据会存入一张历史拉链表中。

在使用中还有了一些心得,补充进来:
使用拉链表的时候可以不加 t_end_date,即失效日期,但是加上之后,能优化很多查询。
可以加上当前行状态标识,能快速定位到当前状态。
在拉链表的设计中可以加一些内容,因为我们每天保存一个状态,如果我们在这个状态里面加一个字段,比如如当天修改次数,那么拉链表的作用就会更大。

tmp_20230111.png
tmp_20230112.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容