數(shù)據(jù)倉庫之拉鏈表詳解

定義:

拉鏈表 - 維護歷史狀態(tài),以及最新狀態(tài)數(shù)據(jù)的一種表,拉鏈表根據(jù)拉鏈粒度的不同,實際上相當(dāng)于快照,只不過做了優(yōu)化,去除了一部分不變的記錄而已,通過拉鏈表可以很方便的還原出拉鏈時點的客戶記錄。

拉鏈表通常是對賬戶信息的歷史變動進行處理保留的結(jié)果。

需求:

  1. 數(shù)據(jù)量比較大;
  2. 表中的部分字段會被update,如用戶的地址,產(chǎn)品的描述信息,訂單的狀態(tài)等等;
  3. 需要查看某一個時間點或者時間段的歷史快照信息,比如,查看某一個訂單在歷史某一個時間點的狀態(tài),
    比如,查看某一個用戶在過去某一段時間內(nèi),更新過幾次等等;
  4. 變化的比例和頻率不是很大,比如,總共有1000萬的會員,每天新增和發(fā)生變化的有10萬左右;
  5. 如果對這邊表每天都保留一份全量,那么每次全量中會保存很多不變的信息,對存儲是極大的浪費;
    拉鏈歷史表,既能滿足反應(yīng)數(shù)據(jù)的歷史狀態(tài),又可以最大程度的節(jié)省存儲;

拉鏈表設(shè)計:

在企業(yè)中,由于有些流水表每日有幾千萬條記錄,數(shù)據(jù)倉庫保存5年數(shù)據(jù)的話很容易不堪重負(fù),因此可以使用拉鏈表的算法來節(jié)省存儲空間。

1.采集當(dāng)日全量數(shù)據(jù)存儲到 ND(當(dāng)日) 表中。
2.可從歷史表中取出昨日全量數(shù)據(jù)存儲到 OD(上日數(shù)據(jù))表中。
3.用ND-OD為當(dāng)日新增和變化的數(shù)據(jù)(即日增量數(shù)據(jù))。

兩個表進行全字段比較,將結(jié)果記錄到tabel_I表中

4.用OD-ND為狀態(tài)到此結(jié)束需要封鏈的數(shù)據(jù)。 (需要修改END_DATE)

兩個表進行全字段比較,將結(jié)果記錄到tabel_U表中
5.歷史表(HIS)比ND表和OD表多兩個字段(START_DATE,END_DATE)
6.將tabel_I表的內(nèi)容全部insert插入到HIS表中。START_DATE='當(dāng)日',END_DATE可設(shè)為'9999-12-31'
7.更新封鏈記錄的END_DATE

歷史表(HIS)和tabel_U表比較,START_DATE,END_DATE除外,以tabel_U表為準(zhǔn),兩者交集將其END_DATE改成當(dāng)日,說明該記錄失效。
8。取數(shù)據(jù)時對日期進行條件選擇即可,如:取20100101日的數(shù)據(jù)為
(where START_DATE<='20100101' and END_DATE>'20100101' )

例子 - 1:

假設(shè)以天為維度,以每天的最后一個狀態(tài)為當(dāng)天的最終狀態(tài)。

以一張訂單表為例,如下是原始數(shù)據(jù),每天的訂單狀態(tài)明細(xì)

1   2016-08-20  2016-08-20  創(chuàng)建

2   2016-08-20  2016-08-20  創(chuàng)建

3   2016-08-20  2016-08-20  創(chuàng)建

1   2016-08-20  2016-08-21  支付

2   2016-08-20  2016-08-21  完成

4   2016-08-21  2016-08-21  創(chuàng)建

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  創(chuàng)建

根據(jù)拉鏈表我們希望得到的是

1  2016-08-20  2016-08-20  創(chuàng)建 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  創(chuàng)建 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  創(chuàng)建 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  創(chuàng)建 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  創(chuàng)建 2016-08-22  9999-12-31

可以看出 1,2,3,4 每個訂單的狀態(tài)都有,并且也能統(tǒng)計到當(dāng)前的有效狀態(tài)。

例子 - 2:

舉個簡單例子,比如有一張訂單表,6月20號有3條記錄:

到6月21日,表中有5條記錄:

到6月22日,表中有6條記錄:

數(shù)據(jù)倉庫中對該表的保留方法:

  1. 只保留一份全量,則數(shù)據(jù)和6月22日的記錄一樣,如果需要查看6月21日訂單001的狀態(tài),則無法滿足;

  2. 每天都保留一份全量,則數(shù)據(jù)倉庫中的該表共有14條記錄,但好多記錄都是重復(fù)保存,沒有任務(wù)變化,如訂單002,004,數(shù)據(jù)量大了,會造成很大的存儲浪費;

如果在數(shù)據(jù)倉庫中設(shè)計成歷史拉鏈表保存該表,則會有下面這樣一張表:

說明:

  1. dw_begin_date表示該條記錄的生命周期開始時間,dw_end_date表示該條記錄的生命周期結(jié)束時間;

  2. dw_end_date = '9999-12-31'表示該條記錄目前處于有效狀態(tài);

  3. 如果查詢當(dāng)前所有有效的記錄,則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日的記錄完全一致:

可以看出,這樣的歷史拉鏈表,既能滿足對歷史數(shù)據(jù)的需求,又能很大程度的節(jié)省存儲資源。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容