新增及變化數據
如下圖所示,2020-01-01爲初始化數據,在2020-01-02的時候jacky約增加了500,數據庫裏又新增了lucy這個新用戶。對於數據倉庫來說jacky就是變化的數據,lucy就是新增的數據。
如何將新增以及變化的數據導入數據倉庫
如果在不佔用過多空間的情況下,又能在保留歷史數據的同時,體現最新的狀態,拉鍊表是一個不錯的選擇
什麼是拉鍊表
如下圖所示,前一日全量數據和當日新增以及變化的數據合併形成一張新的全量表,就像是拉鍊的形狀。
如何實現
如下圖所示,user_info從ods層進入dwd層的時候增加兩個字段,start_date爲生效日期,end_date爲失效日期,當end_date爲9999-12-31的時候表示爲最新數據
應用場景
一般用戶表或者訂單表使用拉鍊表的情況比較多,根據end_date可以追溯每個用戶信息或者訂單狀態的修改狀況
實例應用
創建三個 用戶表
--ods層用戶表
CREATE external TABLE `user.ods_user_info` (
`id` bigint COMMENT '主鍵',
`name` string COMMENT '名字',
`banlance` double COMMENT '餘額',
`create_time` string COMMENT '創建時間',
`modify_time` string COMMENT '更新時間'
)partitioned by (`dt` string)
row format delimited fields terminated by '\t';
--dwd層用戶拉鍊臨時表
CREATE external TABLE `user.dwd_dim_user_info_tmp` (
`id` bigint COMMENT '主鍵',
`name` string COMMENT '名字',
`banlance` double COMMENT '餘額',
`create_time` string COMMENT '創建時間',
`modify_time` string COMMENT '更新時間',
`start_date` string COMMENT '開始時間',
`end_date` string COMMENT '結束時間'
)
STORED AS ORC
TBLPROPERTIES ("orc.compress"="LZO");
--dwd層用戶拉鍊表
CREATE external TABLE `user.dwd_dim_user_info` (
`id` bigint COMMENT '主鍵',
`name` string COMMENT '名字',
`banlance` double COMMENT '餘額',
`create_time` string COMMENT '創建時間',
`modify_time` string COMMENT '更新時間',
`start_date` string COMMENT '開始時間',
`end_date` string COMMENT '結束時間'
)
STORED AS ORC
TBLPROPERTIES ("orc.compress"="LZO");
數據
2020-01-01.txt
1 tom 1000 2020-01-01
2 jacky 1000 2020-01-01
2020-01-02.txt
2 jacky 1500 2020-01-01 2020-01-02
3 lucy 3000 2020-01-02
#裝載數據第一天數據
hive -e "load data inpath '/input/user/2020-01-01.txt' into table user.ods_user_info partition(dt='2020-01-01');"
#初始化拉鍊表
hive -e "insert into user.dwd_dim_user_info select id,name,banlance,create_time,modify_time,'2020-01-01','9999-12-31' from user.ods_user_info;"
hive -e "select * from user.ods_user_info"
#裝載數據第二天數據
hive -e "load data inpath '/input/user/2020-01-02.txt' into table user.ods_user_info partition(dt='2020-01-02');"
#將舊數據和新增變化數據插入臨時拉鍊表
hive -e "insert overwrite table user.dwd_dim_user_info_tmp
select
a.id,a.name,a.banlance,a.create_time,a.modify_time,a.start_date,
if(b.id is not null and a.end_date='9999-12-31',date_sub('2020-01-02',1),a.end_date)
from
user.dwd_dim_user_info a
left join
(select * from `user.ods_user_info` where dt='2020-01-02') b
on
a.id=b.id
union all
select id,name,banlance,create_time,modify_time,'2020-01-02','9999-12-31' from user.ods_user_info where dt='2020-01-02'"
hive -e "insert overwrite table user.dwd_dim_user_info select * from user.dwd_dim_user_info_tmp"
hive -e "select * from user.dwd_dim_user_info"