Mysql數據準備css
第一天 9月10號數據mysql
1,待支付,2020-09-10 12:20:11,2020-09-10 12:20:112,待支付,2020-09-10 14:20:11,2020-09-10 14:20:113,待支付,2020-09-10 16:20:11,2020-09-10 16:20:11
次日 9月11號數據
web
1,待支付,2020-09-10 12:20:11,2020-09-10 12:20:112,已支付,2020-09-10 14:20:11,2020-09-11 14:21:113,已支付,2020-09-10 16:20:11,2020-09-11 16:21:114,待支付,2020-09-11 12:20:11,2020-09-11 12:20:115,待支付,2020-09-11 14:20:11,2020-09-11 14:20:11
對比mysql第一天和次日的數據發現,次日新增了訂單id爲4和5這兩條數據,而且訂單id爲2和3的狀態更新爲了已支付
面試
全量表sql
天天的全部的最新狀態的數據。微信
一、全量表,有無變化,都要報架構
二、每次上報的數據都是全部的數據(變化的 + 沒有變化的)app
9月10號全量抽取到ods層
編輯器
create table wedw_ods.order_info_20200910( order_id string COMMENT '訂單id',order_status string COMMENT '訂單狀態',create_time timestamp COMMENT '建立時間',update_time timestamp COMMENT '更新時間') COMMENT '訂單表'row format delimited fields terminated by ',';
create table wedw_dwd.order_info_df( order_id string COMMENT '訂單id',order_status string COMMENT '訂單狀態',create_time timestamp COMMENT '建立時間',update_time timestamp COMMENT '更新時間') COMMENT '訂單表'partitioned by (date_id string)row format delimited fields terminated by ',';
# 把wedw_ods.order_info_20200910數據全量插到dwd層2020-09-10分區insert overwrite table wedw_dwd.order_info_df partition(date_id = '2020-09-10')selectorder_id,order_status,create_time,update_timefrom wedw_ods.order_info_20200910;
9月11號全量抽取到ods層oop
create table wedw_ods.order_info_20200911( order_id string COMMENT '訂單id',order_status string COMMENT '訂單狀態',create_time timestamp COMMENT '建立時間',update_time timestamp COMMENT '更新時間') COMMENT '訂單表'row format delimited fields terminated by ',';
# 把wedw_ods.order_info_20200911數據全量插到dwd層2020-09-11分區insert overwrite table wedw_dwd.order_info_df partition(date_id = '2020-09-11')selectorder_id,order_status,create_time,update_timefrom wedw_ods.order_info_20200911;
全量抽取,每一個分區保留歷史全量快照。
增量表
增量表:新增數據,增量數據是上次導出以後的新數據。
一、記錄每次增長的量,而不是總量;
二、增量表,只報變化量,無變化不用報
三、業務庫表中需有主鍵及建立時間,修改時間
9月10號全量抽取到ods層(全量初始化)
# 把wedw_ods.order_info_20200910數據全量插到dwd層2020-09-10分區insert overwrite table wedw_dwd.order_info_di partition(date_id = '2020-09-10')selectorder_id,order_status,create_time,update_timefrom wedw_ods.order_info_20200910;
9月11號抽取更新的數據及當天新增的數據,即訂單id爲2,3,4,5的數據
wedw_dwd.order_info_di表9月10號的分區數據與wedw_ods.order_info_20200911增量抽取的數據合併,有2種方案
a.兩個表經過主鍵關聯,dwd表存在而且ods表不存在的數據
union all 一下wedw_ods.order_info_20200911表全部的數據,即全量數據插入到dwd表的9月11號的分區
insert overwrite table wedw_dwd.order_info_di partition(date_id = '2020-09-11')select t1.order_id,t1.order_status,t1.create_time,t1.update_timefromwedw_dwd.order_info_di t1left joinwedw_ods.order_info_20200911 t2on t1.order_id = t2.order_idwhere t1.date_id = '2020-09-10'and t2.order_id is nullunion allselect order_id,order_status,create_time,update_timefrom wedw_ods.order_info_20200911;
b.兩個表數據union all一下,再根據order_id去重(根據order分組,更新時間降序,取第一條)
insert overwrite table wedw_dwd.order_info_di partition(date_id = '2020-09-11')select t2.order_id,t2.order_status,t2.create_time,t2.update_time from( select t1.order_id ,t1.order_status ,t1.create_time ,t1.update_time ,row_number() over(partition by order_id order by update_time desc) as rn from ( select order_id ,order_status ,create_time ,update_time from wedw_dwd.order_info_di where date_id = '2020-09-10' union all select order_id ,order_status ,create_time ,update_time from wedw_ods.order_info_20200911 ) t1) t2where t2.rn = 1;
特殊增量表:da表,天天的分區就是當天的數據,其數據特色就是數據產生後就不會發生變化,如日誌表。
拉鍊表
維護歷史狀態,以及最新狀態數據
適用狀況:
1.數據量比較大
2.表中的部分字段會被更新
3.須要查看某一個時間點或者時間段的歷史快照信息
查看某一個訂單在歷史某一個時間點的狀態
某一個用戶在過去某一段時間,下單次數
4.更新的比例和頻率不是很大
若是表中信息變化不是很大,天天都保留一份全量,那麼每次全量中會保存不少不變的信息,對存儲是極大的浪費
優勢
一、知足反應數據的歷史狀態
二、最大程度節省存儲
9月10號全量抽取到ods層
create table wedw_ods.order_info_20200910( order_id string COMMENT '訂單id',order_status string COMMENT '訂單狀態',create_time timestamp COMMENT '建立時間',update_time timestamp COMMENT '更新時間') COMMENT '訂單表'row format delimited fields terminated by ',';
創建dwd層拉鍊表
增長兩個字段:
start_dt(表示該條記錄的生命週期開始時間——週期快照時的狀態)
end_dt(該條記錄的生命週期結束時間)
end_dt= ‘9999-12-31’ 表示該條記錄目前處於有效狀態
create table wedw_dwd.order_info_dz( order_id string COMMENT '訂單id',order_status string COMMENT '訂單狀態',create_time timestamp COMMENT '建立時間',update_time timestamp COMMENT '更新時間',start_dt date COMMENT '開始生效日期',end_dt date COMMENT '結束生效日期') COMMENT '訂單表'partitioned by (date_id string)row format delimited fields terminated by ',';
注:第一次加工的時候須要初始化全部數據,start_time設置爲數據日期2020-09-10 ,end_time設置爲9999-12-31
insert overwrite table wedw_dwd.order_info_dz partition(date_id = '2020-09-10')select order_id ,order_status,create_time ,update_time ,to_date(update_time) as start_dt ,'9999-12-31' as end_dt fromwedw_ods.order_info_20200910;
9月11號抽取更新的數據及當天新增的數據到ods層,即訂單id爲2,3,4,5的數據
insert overwrite table wedw_dwd.order_info_dz partition(date_id = '2020-09-11')select t1.order_id ,t1.order_status,t1.create_time ,t1.update_time,t1.start_dt,case when t1.end_dt = '9999-12-31' and t2.order_id is not null then t1.date_id else t1.end_dt end as end_dtfromwedw_dwd.order_info_dz t1left join wedw_ods.order_info_20200911 t2on t1.order_id = t2.order_idwhere t1.date_id = '2020-09-10'union allSELECT t1.order_id ,t1.order_status,t1.create_time ,t1.update_time,to_date(update_time) as start_dt,'9999-12-31' as end_dtFROM wedw_ods.order_info_20200911 t1;
查詢當前的全部有效記錄:
select * from wedw_dwd.order_info_dz where date_id = '2020-09-11'and end_dt ='9999-12-31';
查詢9月10號歷史快照:
select * from wedw_dwd.order_info_dz where date_id = '2020-09-10' and start_dt <= '2020-09-10' and end_dt >='2020-09-10';
查詢9月11號歷史快照:
select * from wedw_dwd.order_info_dz where date_id = '2020-09-11' and start_dt <= '2020-09-11' and end_dt >='2020-09-11';
總結
不知道以上的一些例子你們有沒有看明白呢?
在工做中,其實上述3種表都是頗有可能會用到的,那麼咱們應該怎麼選擇呢?
若是數據量不是很大(不超過20W)且預估後續增加的很是慢,能夠考慮全量表抽取,這是最簡便的方法
若是數據量目前來講不是很大,可是業務發展很快,數據量一段時間後就會上來,建議增量抽取哦
目前數據量自己就很是大,確定是須要增量抽取的,好比如今有10億數據,若是你天天全量抽取一遍,相信我,你會抽哭的
對於歷史狀態須要保存的,這個時候就須要使用拉鍊表了,實際工做中,使用拉鍊表的場景並不會太多,好比訂單表,保存訂單歷史狀態,維表(緩慢變化維的處理)
本文分享自微信公衆號 - 大數據私房菜(datagogogo)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。