一.全量表
每天的所有的最新狀態的數據。
- 全量表,有無變化,都要報
- 每次上報的數據都是所有的數據(變化的 + 沒有變化的)
2020-04-06 mysql對應的user_info表
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
date_id = ‘2020-04-06’ 數倉表wedw_dwd.test_user_info_df(抽取user_info表所有數據)
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
date_id(分區) |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
2020-04-07 mysql對應的user_info
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
0003 |
李四 |
18 |
333333 |
2020-04-07 |
2020-04-07 |
date_id = ‘2020-04-07’ 數倉表wedw_dwd.test_user_info_df(抽取user_info表所有數據)
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
date_id(分區) |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
2020-04-07 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
2020-04-07 |
0003 |
李四 |
18 |
333333 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
二.增量
增量表:新增數據,增量數據是上次導出之後的新數據。
(1)記錄每次增加的量,而不是總量;
(2)增量表,只報變化量,無變化不用報
(3)每天一個分區
2020-04-06 mysql對應的user_info表
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
date_id = ‘2020-04-06’ 數倉表wedw_dwd.test_user_info_di(第一次初始化的時候抽取user_info表所有數據)
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
date_id(分區) |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
2020-04-07 mysql對應的user_info表
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222444 |
2020-04-06 |
2020-04-07 |
0003 |
李四 |
18 |
333333 |
2020-04-07 |
2020-04-07 |
數倉表wedw_ods.test_user_info_20200407表的數據
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0002 |
小紅 |
21 |
222444 |
2020-04-06 |
2020-04-07 |
0003 |
李四 |
18 |
333333 |
2020-04-07 |
2020-04-07 |
date_id = ‘2020-04-07’ 數倉表wedw_dwd.test_user_info_di的數據
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
date_id(分區) |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
2020-04-07 |
0002 |
小紅 |
21 |
222444 |
2020-04-06 |
2020-04-07 |
2020-04-07 |
0003 |
李四 |
18 |
333333 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
注:因爲數倉都是T+1的,所以7號的數據是8號加工出來的
加工邏輯:
- 根據修改時間,把修改時間等於昨天(即7號)的數據抽取到ods層wedw_ods.test_user_info_20200407中
- 和數倉表wedw_dwd.test_user_info_di 分區date_id = ‘2020-04-06’通過主鍵用戶id進行關聯,先把wedw_dwd.test_user_info_d存在並且wedw_ods.test_user_info_20200407不存在的數據插入到wedw_dwd.test_user_info_di分區date_id=2020-04-07中
- 最後把wedw_ods.test_user_info_20200407表的所有數據插入到wedw_dwd.test_user_info_di分區date_id=2020-04-07
insert overwrite table wedw_dwd.test_user_info_di PARTITION(date_id='2020-04-07')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
from wedw_dwd.test_user_info_di a
left join wedw_ods.test_user_info_20200407 b
on b.user_id=a.user_id
where a.date_id = '2020-04-06'
and b.user_id is null;
insert into table wedw_dwd.test_user_info_di PARTITION(date_id='2020-04-07')
select
coalesce(user_id'-99') as user_id
,coalesce(user_name,'-99') as user_name
,coalesce(user_age,0) as user_age
,coalesce(user_cellphone,'-99') as user_cellphone
,coalesce(create_time,cast('1700-01-01 00:00:00' as timestamp )) as create_time
,coalesce(update_time,cast('1700-01-01 00:00:00' as timestamp )) as update_time
from wedw_ods.test_user_info_20200407 b ;
--僅保留近7天的分區
alter table wedw_dwd.test_user_info_di drop if EXISTS partition(date_id='2020-03-31');
特殊增量表:da表,每天的分區就是當天的數據,其數據特點就是數據產生後就不會發生變化,如日誌表
三.拉鍊表
維護歷史狀態,以及最新狀態數據
適用情況:
1.數據量比較大
2.表中的部分字段會被更新
3.需要查看某一個時間點或者時間段的歷史快照信息
查看某一個訂單在歷史某一個時間點的狀態
某一個用戶在過去某一段時間,下單次數
4.更新的比例和頻率不是很大
如果表中信息變化不是很大,每天都保留一份全量,那麼每次全量中會保存很多不變的信息,對存儲是極大的浪費
優點
- 滿足反應數據的歷史狀態
- 最大程度節省存儲
2020-04-06 mysql對應的user_info表
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
2020-04-07 mysql對應的user_info表
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111222 |
2020-04-06 |
2020-04-07 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
0003 |
李四 |
22 |
333333 |
2020-04-07 |
2020-04-07 |
0004 |
王五 |
44 |
444444 |
2020-04-07 |
2020-04-07 |
2020-04-08 mysql對應的user_info表
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
0001 |
張三 |
20 |
111233 |
2020-04-06 |
2020-04-08 |
0002 |
小紅 |
21 |
222221 |
2020-04-06 |
2020-04-08 |
0003 |
李四 |
22 |
333333 |
2020-04-07 |
2020-04-07 |
0004 |
王五 |
44 |
444445 |
2020-04-07 |
2020-04-08 |
005 |
德瑪 |
55 |
555555 |
2020-04-08 |
2020-04-08 |
歷史拉鍊表:分區date_id=’2020-04-08’的數倉表wedw_dwd.test_user_info_dz
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
start_time |
end_time |
date_id |
0001 |
張三 |
20 |
111111 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
2020-04-08 |
0001 |
張三 |
20 |
111222 |
2020-04-06 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
2020-04-08 |
0001 |
張三 |
20 |
111233 |
2020-04-06 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
2020-04-07 |
2020-04-08 |
0002 |
小紅 |
21 |
222221 |
2020-04-06 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
0003 |
李四 |
22 |
333333 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
9999-12-31 |
2020-04-08 |
0004 |
王五 |
44 |
444444 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
2020-04-08 |
0004 |
王五 |
44 |
444445 |
2020-04-07 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
005 |
德瑪 |
55 |
555555 |
2020-04-08 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
增加兩個字段:
start_time(表示該條記錄的生命週期開始時間——週期快照時的狀態)
end_time(該條記錄的生命週期結束時間)
end_time= ‘9999-12-31’ 表示該條記錄目前處於有效狀態
查詢當前所有有效的記錄:
select * from wedw_dwd.test_user_info_dz where date_id = ‘2020-04-08’ and end_time = ‘9999-12-31’;
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
start_time |
end_time |
date_id |
0001 |
張三 |
20 |
111233 |
2020-04-06 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
0002 |
小紅 |
21 |
222221 |
2020-04-06 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
0003 |
李四 |
22 |
333333 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
9999-12-31 |
2020-04-08 |
0004 |
王五 |
44 |
444445 |
2020-04-07 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
005 |
德瑪 |
55 |
555555 |
2020-04-08 |
2020-04-08 |
2020-04-08 |
9999-12-31 |
2020-04-08 |
查詢2020-04-07的歷史快照:
select * from wedw_dwd.test_user_info_dz where date_id = ‘2020-04-08’ and start_time <= ‘2020-04-07’ and end_time >= ‘2020-04-07’;
用戶id |
姓名 |
年齡 |
手機號 |
創建時間 |
修改時間 |
start_time |
end_time |
date_id |
0001 |
張三 |
20 |
111222 |
2020-04-06 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
2020-04-08 |
0002 |
小紅 |
21 |
222222 |
2020-04-06 |
2020-04-06 |
2020-04-06 |
2020-04-07 |
2020-04-08 |
0003 |
李四 |
22 |
333333 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
9999-12-31 |
2020-04-08 |
0004 |
王五 |
44 |
444444 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
2020-04-07 |
2020-04-08 |
加工邏輯:
注:第一次加工的時候需要初始化所有數據,start_time設置爲數據日期2020-04-06 ,end_time設置爲9999-12-31
--分桶
set hive.enforce.bucketing=FALSE;
--分區
set hive.exec.dynamic.partition=FALSE;
set hive.exec.dynamic.partition.mode=nostrick;
set hive.exec.compress.output=true;
set mapred.output.compress=true;
set mapred.output.compression.type=BLOCK;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
alter table wedw_dwd.test_user_info_dz drop if EXISTS PARTITION(date_id='${HIVE_DATA_DATE}');
-- wedw_dwd.test_user_info_dz 存在, wedw_ods.test_user_info_${DATA_DATE} 不存在的
--或者都存在的閉鏈的 插入到 wedw_dwd.test_user_info_dz 下一個分區
insert overwrite table wedw_dwd.test_user_info_dz PARTITION(date_id='${HIVE_DATA_DATE}')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
,a.start_time
,a.end_time
from wedw_dwd.test_user_info_dz a
left join wedw_ods.test_user_info_${DATA_DATE} b on b.user_id=a.user_id and b.create_time < '${HIVE_DATA_DATE+1}'
where a.date_id = '${HIVE_DATA_DATE-1}'
and (b.user_id is null
or (b.user_id is not null and a.end_time <='${HIVE_DATA_DATE-1}')
)
;
-- 把wedw_dwd.test_user_info_dz, wedw_ods.test_user_info_${DATA_DATE} 都存在的開鏈的 全部閉鏈 插入到 wedw_dwd.test_user_info_dz 下一個分區
insert into table wedw_dwd.test_user_info_dz PARTITION(date_id='${HIVE_DATA_DATE}')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
,a.start_time
,'${HIVE_DATA_DATE-1}' end_time
from wedw_dwd.test_user_info_dz a
inner join wedw_ods.test_user_info_${DATA_DATE} b on b.user_id=a.user_id and b.create_time < '${HIVE_DATA_DATE+1}'
where a.date_id = '${HIVE_DATA_DATE-1}'
and a.end_time >'${HIVE_DATA_DATE-1}'
;
-- 把wedw_ods.test_user_info_${DATA_DATE}, 插入到 wedw_dwd.test_user_info_dz 下一個分區
insert into table wedw_dwd.test_user_info_dz PARTITION(date_id='${HIVE_DATA_DATE}')
select
a.user_id
,a.user_name
,a.user_age
,a.user_cellphone
,a.create_time
,a.update_time
,'${HIVE_DATA_DATE}' start_time,
,'9999-12-31' end_time
from wedw_ods.test_user_info_${DATA_DATE} b
where b.create_time < '${HIVE_DATA_DATE+1}';
--僅保留近7天的數據
alter table wedw_dwd.test_user_info_dz drop if EXISTS partition(date_id='${HIVE_DATA_DATE-7}');
四.流水錶
對於表中的每一個修改都會記錄,可以用於反映實際記錄的變更
五.快照表
每一天的數據都是截止到那一天mysql(數據源)的全量數據