定義:
拉鍊表 - 維護歷史狀態,以及最新狀態數據的一種表,拉鍊表根據拉鍊粒度的不同,實際上相當於快照,只不過做了優化,去除了一部分不變的記錄而已,通過拉鍊表可以很方便的還原出拉鍊時點的客戶記錄。
拉鍊表通常是對賬戶信息的歷史變動進行處理保留的結果。
需求:
1. 數據量比較大;
2. 表中的部分字段會被update,如用戶的地址,產品的描述信息,訂單的狀態等等;
3. 需要查看某一個時間點或者時間段的歷史快照信息,比如,查看某一個訂單在歷史某一個時間點的狀態,
比如,查看某一個用戶在過去某一段時間內,更新過幾次等等;
4. 變化的比例和頻率不是很大,比如,總共有1000萬的會員,每天新增和發生變化的有10萬左右;
5. 如果對這邊表每天都保留一份全量,那麼每次全量中會保存很多不變的信息,對存儲是極大的浪費;
拉鍊歷史表,既能滿足反應數據的歷史狀態,又可以最大程度的節省存儲;
拉鍊表設計:
在企業中,由於有些流水錶每日有幾千萬條記錄,數據倉庫保存5年數據的話很容易不堪重負,因此可以使用拉鍊表的算法來節省存儲空間。
1.採集當日全量數據存儲到 ND(當日) 表中。
2.可從歷史表中取出昨日全量數據存儲到 OD(上日數據)表中。
3.用ND-OD爲當日新增和變化的數據(即日增量數據)。
兩個表進行全字段比較,將結果記錄到tabel_I表中
4.用OD-ND爲狀態到此結束需要封鏈的數據。 (需要修改END_DATE)
兩個表進行全字段比較,將結果記錄到tabel_U表中
5.歷史表(HIS)比ND表和OD表多兩個字段(START_DATE,END_DATE)
6.將tabel_I表的內容全部insert插入到HIS表中。START_DATE='當日',END_DATE可設爲'9999-12-31'
7.更新封鏈記錄的END_DATE
歷史表(HIS)和tabel_U表比較,START_DATE,END_DATE除外,以tabel_U表爲準,兩者交集將其END_DATE改成當日,說明該記錄失效。
8。取數據時對日期進行條件選擇即可,如:取20100101日的數據爲
(where START_DATE<='20100101' and END_DATE>'20100101' )
例子 - 1:
假設以天爲維度,以每天的最後一個狀態爲當天的最終狀態。
以一張訂單表爲例,如下是原始數據,每天的訂單狀態明細
1 2016-08-20 2016-08-20 創建
2 2016-08-20 2016-08-20 創建
3 2016-08-20 2016-08-20 創建
1 2016-08-20 2016-08-21 支付
2 2016-08-20 2016-08-21 完成
4 2016-08-21 2016-08-21 創建
1 2016-08-20 2016-08-22 完成
3 2016-08-20 2016-08-22 支付
4 2016-08-21 2016-08-22 支付
5 2016-08-22 2016-08-22 創建
根據拉鍊表我們希望得到的是
1 2016-08-20 2016-08-20 創建 2016-08-20 2016-08-20
1 2016-08-20 2016-08-21 支付 2016-08-21 2016-08-21
1 2016-08-20 2016-08-22 完成 2016-08-22 9999-12-31
2 2016-08-20 2016-08-20 創建 2016-08-20 2016-08-20
2 2016-08-20 2016-08-21 完成 2016-08-21 9999-12-31
3 2016-08-20 2016-08-20 創建 2016-08-20 2016-08-21
3 2016-08-20 2016-08-22 支付 2016-08-22 9999-12-31
4 2016-08-21 2016-08-21 創建 2016-08-21 2016-08-21
4 2016-08-21 2016-08-22 支付 2016-08-22 9999-12-31
5 2016-08-22 2016-08-22 創建 2016-08-22 9999-12-31
可以看出 1,2,3,4 每個訂單的狀態都有,並且也能統計到當前的有效狀態。
例子 - 2:
舉個簡單例子,比如有一張訂單表,6月20號有3條記錄:
到6月21日,表中有5條記錄:
到6月22日,表中有6條記錄:
數據倉庫中對該表的保留方法:
1. 只保留一份全量,則數據和6月22日的記錄一樣,如果需要查看6月21日訂單001的狀態,則無法滿足;
2. 每天都保留一份全量,則數據倉庫中的該表共有14條記錄,但好多記錄都是重複保存,沒有任務變化,如訂單002,004,數據量大了,會造成很大的存儲浪費;
如果在數據倉庫中設計成歷史拉鍊表保存該表,則會有下面這樣一張表:
說明:
1. dw_begin_date表示該條記錄的生命週期開始時間,dw_end_date表示該條記錄的生命週期結束時間;
2. dw_end_date = '9999-12-31'表示該條記錄目前處於有效狀態;
3. 如果查詢當前所有有效的記錄,則select * from order_his where dw_end_date = '9999-12-31'
4. 如果查詢2012-06-21的歷史快照,則select * from order_his where dw_begin_date <= '2012-06-21' and end_date >= '2012-06-21',這條語句會查詢到以下記錄:
和源表在6月21日的記錄完全一致:
可以看出,這樣的歷史拉鍊表,既能滿足對歷史數據的需求,又能很大程度的節省存儲資源;
原文:https://blog.csdn.net/u012965373/article/details/81515463