拉链表 ---- 因为hive 不能进行update操作,基于这个前提我们实现拉链表.
拉链表适用于同步新增和变化的数据.
记录了一个事务从开始,一直到当前状态的变化信息,需要查看某一个事件点或者历史段的历史快照信息.
设计拉链表我们会增加两个字段 一个是starttime 一个是endtime ,用来记录该条记录的生命周期的开始事件和该条记录的结束事件, endtime = 9999-12-31的话,表明该条记录为处于有效状态.
拉链表的性能调优
1. 对start_date和end_date做索引,这样能提高不少性能。
2. 保留部分历史数据,暴露一张只提供近3个月数据的拉链表
从原拉链表中查询历史数据,同事对和今天新增数据id相同的数据的end_date进行修改.
1.创建拉链表
hive (gmall)> drop table if exists dwd_order_info_his; create external table dwd_order_info_his( `id` string COMMENT '订单编号', `total_amount` decimal(10,2) COMMENT '订单金额', `order_status` string COMMENT '订单状态', `user_id` string COMMENT '用户id' , `payment_way` string COMMENT '支付方式', `out_trade_no` string COMMENT '支付流水号', `create_time` string COMMENT '创建时间', `operate_time` string COMMENT '操作时间', `start_date` string COMMENT '有效开始日期', `end_date` string COMMENT '有效结束日期' ) COMMENT '订单拉链表' stored as parquet location '/ /gmall/dwd/dwd_order_info_his/' tblproperties ("parquet.compression"="snappy");
2.初始化拉链表
hive (gmall)> insert overwrite table dwd_order_info_his select id, total_amount, order_status, user_id, payment_way, out_trade_no, create_time, operate_time, '2019-12-16', '9999-99-99' from ods_order_info oi where oi.dt='2019-12-16';
3.创建临时表
hive (gmall)> drop table if exists dwd_order_info_his_tmp; create table dwd_order_info_his_tmp( `id` string COMMENT '订单编号', `total_amount` decimal(10,2) COMMENT '订单金额', `order_status` string COMMENT '订单状态', `user_id` string COMMENT '用户id' , `payment_way` string COMMENT '支付方式', `out_trade_no` string COMMENT '支付流水号', `create_time` string COMMENT '创建时间', `operate_time` string COMMENT '操作时间', `start_date` string COMMENT '有效开始日期', `end_date` string COMMENT '有效结束日期' ) COMMENT '订单拉链临时表' stored as parquet location '/warehouse/gmall/dwd/dwd_order_info_his_tmp/' tblproperties ("parquet.compression"="snappy");
向临时表中插入数据
hive (gmall)> insert overwrite table dwd_order_info_his_tmp select * from ( select id, total_amount, order_status, user_id, payment_way, out_trade_no, create_time, operate_time, '2019-02-14' start_date, '9999-99-99' end_date from dwd_order_info where dt='2019-02-14' union all select oh.id, oh.total_amount, oh.order_status, oh.user_id, oh.payment_way, oh.out_trade_no, oh.create_time, oh.operate_time, oh.start_date, if(oi.id is null, oh.end_date, date_add(oi.dt,-1)) end_date from dwd_order_info_his oh left join ( select * from dwd_order_info where dt='2019-02-14' ) oi on oh.id=oi.id and oh.end_date='9999-99-99' )his order by his.id, start_date;
把临时表覆盖给拉链表
hive (gmall)> insert overwrite table dwd_order_info_his select * from dwd_order_info_his_tmp;