資料儲存方式之歷史拉鍊

2021-08-27 16:26:11 字數 2916 閱讀 4674

取最新的資料:v_data_date = '99991231'

取當天的全量:v_data_date between sdate and edate

取當天的增量:sdate = v_data_date

流程:1.判斷是否重跑,如果重跑,將不應該存在的日期的資料刪掉,當日的也要刪,將閉鏈的資料重新開鏈

2.如果不是重跑,用目標表minus源表,得到上游系統刪除了的資料並將其閉鏈,再用源表minus目標表,得到上游系統的增變數,將其插入到目標表,變化了的資料閉鏈

偽**:

目標表:dt,源表 st,臨時表tt,主鍵pk,其他欄位oclm,開始日期sdate,結束日期edate,跑批日期v_data_date,昨天v_last_date,99991231 v_edate

1.判斷是否重跑 如果是,則需要刪掉當天及以後所有新增的資料,修改掉當天及以後閉鏈了的資料

首先刪掉所有新增的資料,包括當天的和當天以後的所有的

delete from dt where sdate>=v_data_date

然後修改掉當天及以後閉鏈了的資料,可採用先insert 再 delete 或者 update的方式,update的方式便於理解,但是效率較差,下面是insert 再delete 的方式將閉鏈資料重新開鏈

insert into dt

select sdate,v_edate,pk,oclm

from dt

where edate>=v_last_date and edate = v_edate;

delete from dt where edate>=v_last_date and edate = v_edate;

commit;

下面是update的方式將閉鏈資料重新開鏈,和上面的選乙個就行,不用都有

update dt set edate = v_edate where edate>=v_last_date and edate = v_edate;

以上處理完重跑的資料,開始正式處理新來的資料

首先,將源系統刪除了的資料閉鏈,用v_last_date那天的全量資料和源表(當天資料)的主鍵進行對比,找到刪除了的資料,放到臨時表,記得放之前清空臨時表

truncate table tt;

insert into tt

select pk

from dt

where v_last_date between sdate and edate

minus 

select pk

from st

如果臨時表裡有資料,就說明有刪除了的資料,要將其閉鏈,方式是用臨時表和源表關聯,如果關聯的上,說明臨時表裡有,然後根據主鍵,將其閉鏈,先插入閉鏈資料,再刪除未閉鏈資料,同樣可以採用update的寫法

insert into dt sdate,edate,pk,oclm

select sdate,v_last_date,pk,oclm

from dt

where exits(select 'x' from tt where tt.pk = dt.pk)

and edate = v_edate

delete from dt where exists(select 'x' from tt where tt.pk = dt.pk)

and edate = v_edate

update寫法:

update dt set edate where exists(select 'x' from tt where tt.pk = dt.pk)

and edate = v_edate

以上反減結束,處理完上游刪除了的資料,接下來處理增變數的資料,首先清空臨時表tt,然後用源表minus目標表得到增變數資料放到臨時表裡,然後將臨時表和目標表關聯,關聯上的資料就是增變數資料,然後將變化了的資料閉鏈,然後插入所有增變數到目標表dt

truncate table tt;

insert into tt pk,oclm

select pk,oclm

from st

minus

select pk,oclm

from dt

where v_last_date between sdate and edate

commit;

insert into dt

select sdate,v_last_date as edaet ,pk,oclm

from dt

where exists (select 'x' from tt where tt.pk = dt.pk)

and edate = v_edate

delete from dt 

where exists (select 'x' from tt where tt.pk = dt.pk)

and edate = v_edate

commit;

此次閉鏈依然可以採用update的方式

update dt set edate = v_last_date where exists (select 'x' from tt where tt.pk = dt.pk)

and edate = v_edate

以上將所有當日變化了的資料閉鏈完畢,還需將新增的資料和閉鏈了的資料的最新資料插入到目標表

insert into dt

select sdate,v_edate,pk,oclm

from tt

commit;

到此結束整個拉鍊流程

注意:清空臨時表盡量不要用execute immediate 的方式,因為這種方式是硬解析,慢,而且會遮蔽掉隱含的錯誤,在編譯的時候看不出來,只有執行的時候才會看出來,所以沒必要把使用者名稱和表名寫成引數傳進去,直接寫死,快,又不會出現編譯看不出來的錯

記錄資料條數一定要在commit前,v_cnt := sql%rowcount,否則一提交這個值就是0了,就起不了作用了

資料倉儲歷史資料儲存 拉鍊表

假如我們有乙個賬號account表,我們需要在hive中儲存 資料是從線上mysql讀取binlog同步來的,是有明細變化的 account表結構 account id,username,followers count,modified at我們經常使用的儲存方式有快照表和流水表。快照表就是以時間為...

拉鍊式儲存 極限儲存之拉鍊表

在資料倉儲的資料模型設計過程中,經常會遇到這樣的需求 1.資料量比較大 2.表中的部分欄位會被update,如使用者的位址,產品的描述資訊,訂單的狀態等等 3.需要檢視某乙個時間點或者時間段的歷史快照資訊,比如,檢視某乙個訂單在歷史某乙個時間點的狀態,比如,檢視某乙個使用者在過去某一段時間內,更新過...

極限儲存之拉鍊表

在資料倉儲的資料模型設計過程中,經常會遇到這樣的需求 1.資料量比較大 2.表中的部分欄位會被update,如使用者的位址,產品的描述資訊,訂單的狀態等等 3.需要檢視某乙個時間點或者時間段的歷史快照資訊,比如,檢視某乙個訂單在歷史某乙個時間點的狀態,比如,檢視某乙個使用者在過去某一段時間內,更新過...