首页 > 其他 > 详细

数据仓库拉链表

时间:2020-04-22 11:55:38      阅读:72      评论:0      收藏:0      [点我收藏+]

1.什么是拉链表

拉链表是根据数据存储得方式而定义的,记录每天信息的生命周期,一旦一条记录的生命周期结束,就开始新的一条记录,并把当前日期作为生效日期。

技术分享图片

 

 

 

2.为什么要做拉链表

  1. 有一些表的数据量很大,比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。
  2. 表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。
  3. 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。
  4. 表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。

那么对于这种表我该如何设计呢?下面有几种方案可选:

  方案一:每天只留最新的一份,比如我们每天用Sqoop抽取最新的一份全量数据到Hive中。

  方案二:每天保留一份全量的切片数据。

  方案三:使用拉链表

 
我们对上面三个方案分析:
  

  方案一

  这种方案就不用多说了,实现起来很简单,每天drop掉前一天的数据,重新抽一份最新的。

  优点很明显,节省空间,一些普通的使用也很方便,不用在选择表的时候加一个时间分区什么的。

  缺点同样明显,没有历史数据,先翻翻旧账只能通过其它方式,比如从流水表里面抽。

  方案二

  每天一份全量的切片是一种比较稳妥的方案,而且历史数据也在。

  缺点就是存储空间占用量太大太大了,如果对这边表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极大的浪费,这点我感触还是很深的......

  当然我们也可以做一些取舍,比如只保留近一个月的数据?但是,需求是无耻的,数据的生命周期不是我们能完全左右的。

  拉链表

  拉链表在使用上基本兼顾了我们的需求。

  首先它在空间上做了一个取舍,虽说不像方案一那样占用量那么小,但是它每日的增量可能只有方案二的千分之一甚至是万分之一。

  其实它能满足方案二所能满足的需求,既能获取最新的数据,也能添加筛选条件也获取历史的数据。


技术分享图片

 

 

 

 3.如何做拉链表

技术分享图片

 

 

 

拉链表制作流程图

技术分享图片

 

 

 

4.拉链表制作

创建拉链表

 1 drop table if exists dwd_order_info_his;
 2 create external table dwd_order_info_his(
 3     `id` string COMMENT 订单编号,
 4     `total_amount` decimal(10,2) COMMENT 订单金额,
 5     `order_status` string COMMENT 订单状态,
 6     `user_id` string COMMENT 用户id ,
 7     `payment_way` string COMMENT 支付方式,
 8     `out_trade_no` string COMMENT 支付流水号,
 9     `create_time` string COMMENT 创建时间,
10     `operate_time` string COMMENT 操作时间,
11     `start_date`  string COMMENT 有效开始日期,
12     `end_date`  string COMMENT 有效结束日期
13 ) COMMENT 订单拉链表
14 stored as parquet
15 location /warehouse/gmall/dwd/dwd_order_info_his/
16 tblproperties ("parquet.compression"="snappy");

初始化拉链表

 1 insert overwrite table dwd_order_info_his
 2 select
 3     id,
 4     total_amount,
 5     order_status,
 6     user_id,
 7     payment_way,
 8     out_trade_no,
 9     create_time,
10     operate_time,
11     2019-02-13,
12     9999-99-99
13 from ods_order_info oi
14 where oi.dt=2019-02-13;

 

  如何获得每日变动表

  (1)最好表内有创建时间和变动时间

  (2)如果没有,可以利用第三方工具监控比如canal,监控MySQL的实时变化进行记录(麻烦)。

  (3)逐行对比前后两天的数据, 检查md5(concat(全部有可能变化的字段))是否相同(low)

  (4)要求业务数据库提供变动流水

 

创建临时表

 

 1 drop table if exists dwd_order_info_his_tmp;
 2 create table dwd_order_info_his_tmp( 
 3     `id` string COMMENT 订单编号,
 4     `total_amount` decimal(10,2) COMMENT 订单金额, 
 5     `order_status` string COMMENT 订单状态, 
 6     `user_id` string COMMENT 用户id ,
 7     `payment_way` string COMMENT 支付方式,  
 8     `out_trade_no` string COMMENT 支付流水号,  
 9     `create_time` string COMMENT 创建时间,  
10     `operate_time` string COMMENT 操作时间,
11     `start_date`  string COMMENT 有效开始日期,
12     `end_date`  string COMMENT 有效结束日期
13 ) COMMENT 订单拉链临时表
14 stored as parquet
15 location /warehouse/gmall/dwd/dwd_order_info_his_tmp/
16 tblproperties ("parquet.compression"="snappy");

 

合并数据到临时表

 //dwd_order_info为存储新增及变化的表
 1 insert overwrite table dwd_order_info_his_tmp
 2 select * from 
 3 (
 4 select 
 5 id,
 6     total_amount,
 7     order_status,
 8     user_id,
 9     payment_way,
10     out_trade_no,
11     create_time,
12     operate_time,
13     2019-02-14 start_date,
14     9999-99-99 end_date
15 from dwd_order_info where dt=2019-02-14
16 
17 union all 
18 select oh.id,
19     oh.total_amount,
20     oh.order_status,
21     oh.user_id,
22     oh.payment_way,
23     oh.out_trade_no,
24     oh.create_time,
25     oh.operate_time,
26     oh.start_date,
27     if(oi.id is null, oh.end_date, date_add(oi.dt,-1)) end_date
28 from dwd_order_info_his oh left join 
29      (
30 select
31 *
32 from dwd_order_info
33 where dt=2019-02-14
34 ) oi
35      on oh.id=oi.id and oh.end_date=9999-99-99  
36 )his 
37 order by his.id, start_date;

 

覆盖原拉链表

insert overwrite table dwd_order_info_his 

 

查询性能

拉链表当然也会遇到查询性能的问题,比如说我们存放了5年的拉链数据,那么这张表势必会比较大,当查询的时候性能就比较低了,个人认为两个思路来解决:

  1. 在一些查询引擎中,我们对start_date和end_date做索引,这样能提高不少性能。
  2. 保留部分历史数据,比如说我们一张表里面存放全量的拉链表数据,然后再对外暴露一张只提供近3个月数据的拉链表。



 

参考文章:https://www.jianshu.com/p/799252156379

数据仓库拉链表

原文:https://www.cnblogs.com/huangguoming/p/12750895.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!