拉鏈表 ---- 因為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;