數據倉庫-拉鏈表, 流水表, 全量表, 增量表, 切片表


數據倉庫-拉鏈表, 流水表, 全量表, 增量表, 切片表

1 增量表
1.1 概念

 

 

增量表:新增數據,增量數據是上次導出之后的新數據。比如說,從24號到25號新增了那些數據,改變了哪些數據,這些都會存儲在增量表的25號分區里面。

記錄每次增加的量,而不是總量;
增量表,只報變化量,無變化不用報
每天一個分區
1.2 例子

 

 

 

 

注:因為數倉都是T+1的,所以7號的數據是8號加工出來的

加工邏輯:

1.根據修改時間,把修改時間等於昨天(即7號)的數據抽取到ods層wedw_ods.test_user_info_20200407中
2.找出20200406未修改的數據放入20200407分區中
和數倉表wedw_dwd.test_user_info_di 分區date_id = ‘2020-04-06’通過主鍵用戶id進行關聯,先把wedw_dwd.test_user_info_di中存在且wedw_ods.test_user_info_20200407中不存在的數據插入到wedw_dwd.test_user_info_di分區date_id=2020-04-07中
3.最后把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表,每天的分區就是當天的數據,其數據特點就是數據產生后就不會發生變化,如日志表

2 全量表
2.1 概念

 

 

每天計算所有的數據,並覆蓋寫入全量表。

全量表,有無變化,都要報
每次上報的數據都是所有的數據(變化的 + 沒有變化的)
只有一個分區(或者說沒有分區)
每次往全量表里面寫數據都會覆蓋之前的數據,所以全量表不能記錄數據歷史變化,只有截止到當前最新的、全量的數據。
2.2 小結
缺點:

無法反映數據歷史變化,只有截止到當天(t+1)最新的、全量的數據。
2.3 例子

 

 3 快照表

 

 

既然全量表無法反映歷史,那么要能查到歷史數據情況又該怎么辦呢?這個時候快照表就派上用途了

按日分區,記錄截止數據日期的全量數據(每個分區里面的數據都是分區時間對應的前一天的所有全量數據,t+1)

快照表,有無變化,都要報
每次上報的數據都是所有的數據(變化的 + 沒有變化的)
每個分區里面的數據都是分區時間對應的前一天的所有全量數據,比如說當前數據表有3個分區,24號,25號,26號。其中,24號分區里面的數據就是從歷史到23號的所有數據,25號分區里面的數據就是從歷史到24號的所有數據,以此類推。
一天一個分區
快照表的25號分區和24號分區(都是t+1,實際時間分別對應26號和25號)的數據相減就是實際時間25號到26號有變化的、增加的數據,也就相當於增量表里面25號分區的數據。

缺點:

數據量大的時候,其實每個分區都存儲了許多重復的數據,非常的浪費存儲空間。
4 拉鏈表
4.1 概念

 

 

拉鏈表目的是解決快照表數據冗余問題,還能維護數據歷史狀態和最新狀態。拉鏈表根據拉鏈粒度的不同,實際上相當於快照,只不過做了優化,去除了一部分不變的記錄而已,通過拉鏈表可以很方便的還原出拉鏈時點的客戶記錄。

拉鏈表記錄截止數據日期的全量數據

記錄一個事物從開始,一直到當前狀態的所有變化的信息;

拉鏈表每次上報的都是歷史記錄的最終狀態,是記錄在當前時刻的歷史總量;

當前記錄存的是當前時間之前的所有歷史記錄的最后變化量(總量);

一般只有一個分區
也可以有分區表,有些不變的數據或者是已經達到狀態終點的數據就會放在分區里面,分區字段一般為開始時間:start_date和結束時間:end_date。一般在該天有效的數據,它的end_date是大於等於該天的日期的。

獲取某一天全量的數據,可以通過表中的start_date和end_date來做篩選,選出固定某一天的數據。例如我想取截止到20190813的全量數據,其where過濾條件就是where start_date<=‘20190813’ and end_date>=20190813。

4.2 小結
適用情況:

數據量比較大
表中的部分字段會被更新
需要查看某一個時間點或者時間段的歷史快照信息
查看某一個訂單在歷史某一個時間點的狀態
某一個用戶在過去某一段時間,下單次數
更新的比例和頻率不是很大
如果表中信息變化不是很大,每天都保留一份全量,那么每次全量中會保存很多不變的信息,對存儲是極大的浪費。此時可以用拉鏈表。
優點

滿足反應數據的歷史狀態
最大程度節省存儲
4.3 例子

 

 

 

 

增加兩個字段:

start_time
表示該條記錄的生命周期開始時間——周期快照時的狀態

end_time
該條記錄的生命周期結束時間

end_time= ‘9999-12-31’ 表示該條記錄目前處於有效狀態

查詢4月8日的所有有效的記錄:

select * from wedw_dwd.test_user_info_dz where date_id = ‘2020-04-08’ and end_time = ‘9999-12-31’;

  

結果如下

 

 查詢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’;

  

結果如下:

 

 

加工邏輯:

注:第一次加工的時候需要初始化所有數據,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}');

 

5 流水表
5.1 概念
對於表的每一個修改都會記錄,可以用於反映實際記錄的變更。

5.2 流水表與拉鏈表區別
拉鏈表通常是對賬戶信息的歷史變動進行處理保留的結果,流水表是每天的交易形成的歷史;
流水表用於統計業務相關情況,拉鏈表用於統計賬戶及客戶的情況
6 切片表
切片表根據基礎表,往往只反映某一個維度的相應數據。其表結構與基礎表結構相同,但數據往往只有某一維度,或者某一個事實條件的數據


轉自https://blog.csdn.net/xingdianp/article/details/110307783

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM