1、拉鏈表:
①記錄每條信息的生命周期為單位
②一旦一條記錄的生命周期結束,就重新開始一條新的記錄,並把當前日期作為此記錄的生效日期
③如果當前信息至今有效,在生效結束日期中填入一個極大值(如9999-12-31、9999-99-99)
用處:
①需要查看某些業務信息的某一個時間點當日的信息
②數據會發生變化,但是大部分是不變的。(無法做每日增量)
③數據量有一定的規模,無法按照每日全量的方法保存 。(無法做每日全量)
2、拉鏈表實例:
現在增量數據從mysql 已經導入到ods層中了:ods_order_info。
①在dwd層中,新建dwd _order_info表,結構和ods_order_info一樣,多了'start_date'、'end_date'兩個字段
drop table if exists dwd _order_info;
create table dwd _order_info(
..........
.........
'start_date' string comment '有效開始日期',
'end_date string comment '有效結束日期'
)comment '訂單拉鏈表'
partioned by ('dt' string) //分區不是必要的
stored as parquet //存儲格式
location '/warehouse/online_trade/dwd/dwd _order_info'
tblproperties("parquet.compression"="snappy") //壓縮算法
拓展一下分區:
①減小查詢范圍
②索引
③數據量巨大
拉鏈表分區與不分區取決於數據量的多少,並且拉鏈表也不是每天做,可能是每周、每個月做也說不定!!!
也就是說,按天分區、按月分區、不分區都是可以的!!
②將ods的增量數據導數據到dwd
insert overwrite table dwd_order_info
select
.....
'2019-01-10', //設置生效日期
'9999-99-99' //有效結束日期
from ods_order_info a where a.dt='2019-01-10' //將ods的數據導進去
③現在dwd_order_info是最新的增量數據,dwd_order_info_his:是HDFS上的以前的拉鏈數據(歷史表),結構和dwd_order_info一樣
新建一張dwd_order_info_tmp,結構和dwd_order_info一樣:
目的是將今天的增量數據,和歷史數據合並。
①如果今天增量中某些記錄,以前已經在歷史表存在,那么對歷史表進行更新,歷史數據有效期設為今天-1
②經過上一步,歷史表 = 今天沒更新的數據 + 今天更新的數據但是有效期設為昨天(已過期) ,那么歷史表(dwd_order_info_his) union all 最新的增量(dwd_order_info) = 最新的數據(dwd_order_info_tmp)
insert overwrite dwd_order_info_tmp
select
.......
.......
t1.start_date,
if(t2.id is null,t1.end_date,date_add('2019-01-10',-1) )
from dwd_order_info_his t1 left join dwd _order_info t2
on t1.id = t2.id and t1.end_date='9999-99-99' //確保join連接的是還未過期的歷史數據,對已過期的歷史數據不做連接
where t2.dt = '2019-01-10' //確保增量數據是今天導入的。
//以歷史表為基表:t2.id is null 表示已過期的歷史數據,那么有效結束日期不變
// if is not null 表示歷史數據中變化量,那么結束日期-1
union all
select * from dwd_order_info where dwd_order_info.dt = '2019-01-10'
//如果今天增量中某些記錄以前沒記錄,那么進行合並到dwd_order_info_tmp表
④更新歷史表
insert overwrite dwd_order_info_his
select ....... from dwd_order_info_tmp
注:不要用select *,強烈不推薦使用
3、拉鏈表中獲取增量問題:
如何獲取mysql中的每日變動表?
①表中設計創建日期、變動日期字段,那么sqoop就能根據變動日期導數據!
②用canal監控mysql的實時變化