拉鏈算法是目前數(shù)據(jù)倉(cāng)庫(kù)領(lǐng)域比較XX的算法之一..通用非常廣.記錄數(shù)據(jù)量很大且為全量實(shí)體記錄歷史的操作庆揪。
例如式曲,某某移動(dòng)通信公司客戶資料,以河北為例缸榛,河北有客戶2800W吝羞,客戶資料每個(gè)一條就是2800W條記錄算上歷史客戶,全量大概有5000W條左右内颗。作為數(shù)據(jù)倉(cāng)庫(kù)來(lái)存儲(chǔ)這些信息幾千萬(wàn)條記錄不算什么钧排。可是要是記錄歷史全量所用到的存儲(chǔ)就非常的龐大均澳。問(wèn)題實(shí)例為:一般正常情況下恨溜,從河北移動(dòng)的BOSS系統(tǒng)上每天采集全量的日數(shù)據(jù)大概為2500W條,歷史存儲(chǔ)每天存儲(chǔ)一個(gè)2500W條的日表找前,存儲(chǔ)三個(gè)月糟袁,就需要3302500W條的數(shù)據(jù)存儲(chǔ)空間,數(shù)據(jù)量為20E躺盛。這只是存儲(chǔ)三個(gè)月的歷史如果存儲(chǔ)更長(zhǎng)時(shí)間則無(wú)法估計(jì)需要的存儲(chǔ)项戴。而用拉鏈算法存儲(chǔ)。每日只是向歷史表(HIS)中添加新增和變化的數(shù)據(jù)量槽惫。每日不過(guò)數(shù)十W條周叮。存儲(chǔ)一年也就是需要5000W條記錄的存儲(chǔ)空間即兩個(gè)日全量的空間。下面詳細(xì)介紹下拉鏈算法:
1.采集當(dāng)日全量存儲(chǔ)到 ND(NewDay)表中躯枢。(比正常的全量表多兩個(gè)字段(START_DATE&END_DATE))
2.可從歷史表中取出昨日全量數(shù)據(jù)存儲(chǔ)到 OD(OldDay)表中则吟。(比正常的全量表多兩個(gè)字段(START_DATE&END_DATE))
3.用ND-OD為當(dāng)日新增和變化的數(shù)據(jù)(即每日增量)。
4.用OD-ND為狀態(tài)到此結(jié)束需要封鏈的數(shù)據(jù)锄蹂。
5.歷史表(HIS)比ND表和OD表多兩個(gè)字段(START_DATE&END_DATE)
6.針對(duì)第三部來(lái)講氓仲,ND和OD表的(START_DATE&END_DATE)分別記錄當(dāng)前日期和最大日期,取意為開(kāi)始日期為當(dāng)前天的數(shù)據(jù)和結(jié)束日期為最大日期。注意OD和ND的START_DATE
ND——OD兩個(gè)表進(jìn)行全字段比較但是(START_DATE&END_DATE)除外敬扛。將結(jié)果記錄到W_I表中
OD——ND兩個(gè)表進(jìn)行全字段比較同樣(START_DATE&END_DATE)除外晰洒。將結(jié)果記錄到W_U表中
7.將W_I表的內(nèi)容全部插入到HIS表中。
8. 對(duì)歷史表(HIS)和OD表比較對(duì)歷史表最更新操作即在歷史表(HIS)中數(shù)據(jù)進(jìn)行更新操作以W_U表為準(zhǔn)啥箭,即對(duì)歷史表與W_U比對(duì)(START_DATE&END_DATE除外)谍珊,在歷史表(HIS)中也在W_U表中的數(shù)據(jù)將其END_DATE改成當(dāng)前天,說(shuō)明該記錄對(duì)當(dāng)前天失效急侥。
9砌滞。取數(shù)據(jù)時(shí)候?qū)θ掌谶M(jìn)行條件選擇即可如:取20080101日的數(shù)據(jù)條件部分為
(where start-date<='20080101' and end_date>20070801 )即可
全部SQL為:
(select * from table(his) where start-date<='20080101' and end_date>20070801 )
下面為具體例子:
OD(在第一天就等于HIS)
用戶標(biāo)志 狀態(tài) 開(kāi)始時(shí)間 結(jié)束時(shí)間
1 1 200712 299901
2 2 200712 299901
3 3 200712 299901
4 4 200712 299901
5 5 200712 299901
ND
用戶標(biāo)志 狀態(tài) 開(kāi)始時(shí)間 結(jié)束時(shí)間
1 2 200801 299901
2 2 200801 299901
3 4 200801 299901
4 4 200801 299901
5 6 200801 299901
W_I=ND-OD
用戶標(biāo)志 狀態(tài) 開(kāi)始時(shí)間 結(jié)束時(shí)間
1 2 200801 299901
3 4 200801 299901
5 6 200801 299901
W_U=OD-ND
用戶標(biāo)志 狀態(tài) 開(kāi)始時(shí)間 結(jié)束時(shí)間
1 1 200712 299901
3 3 200712 299901
5 5 200712 299901
INSERT操作 把I插入到HIS
用戶標(biāo)志 狀態(tài) 開(kāi)始時(shí)間 結(jié)束時(shí)間
1 1 200712 299901
2 2 200712 299901
3 3 200712 299901
4 4 200712 299901
5 5 200712 299901
1 2 200801 299901
3 4 200801 299901
5 6 200801 299901
update操作 按U更新HIS
用戶標(biāo)志 狀態(tài) 開(kāi)始時(shí)間 結(jié)束時(shí)間
1 1 200712 200801
2 2 200712 299901
3 3 200712 200801
4 4 200712 299901
5 5 200712 200801
1 2 200801 299901
3 4 200801 299901
5 6 200801 299901
表結(jié)構(gòu)設(shè)計(jì)之拉鏈表
(一)概念
拉鏈表是針對(duì)數(shù)據(jù)倉(cāng)庫(kù)設(shè)計(jì)中表存儲(chǔ)數(shù)據(jù)的方式而定義的,顧名思義坏怪,所謂拉鏈贝润,就是記錄歷史。記錄一個(gè)事物從開(kāi)始铝宵,一直到當(dāng)前狀態(tài)的所有變化的信息打掘。
在歷史表中對(duì)客戶的一生的記錄可能就這樣幾條記錄,避免了按每一天記錄客戶狀態(tài)造成的海量存儲(chǔ)的問(wèn)題:
(NAME)人名 (START-DATE)開(kāi)始日期 (END-DT)結(jié)束日期 (STAT)狀態(tài)
client 19000101 19070901 H在家
client 19070901 19130901 A小學(xué)
client 19130901 19160901 B初中
client 19160901 19190901 C高中
client 19190901 19230901 D大學(xué)
client 19230901 19601231 E公司
client 19601231 29991231 H退休在家
上面的每一條記錄都是不算末尾的鹏秋,比如到19070901尊蚁,client已經(jīng)在A,而不是H了侣夷。所以除最后一條記錄因?yàn)闋顟B(tài)到目前都未改變的横朋,其余的記錄實(shí)際上在END-DT那天,都不在是該條記錄END-DT那天的狀態(tài)百拓。這種現(xiàn)象可以理解為算頭不算尾叶撒。
(二)算法
1采集當(dāng)日全量數(shù)據(jù)到ND(NewDay)表;
2可從歷史表中取出昨日全量數(shù)據(jù)存儲(chǔ)到OD(OldDay)表;
3(ND-OD)就是當(dāng)日新增和變化的數(shù)據(jù)耐版,也就是當(dāng)天的增量,用W_I表示压汪;
4(OD-ND)為狀態(tài)到此結(jié)束需要封鏈的數(shù)據(jù)粪牲,用W_U表示;
5將W_I表的內(nèi)容全部插入到歷史表中止剖,這些是新增記錄腺阳,start_date為當(dāng)天,而end_date為max值穿香;
6對(duì)歷史表進(jìn)行W_U部份的更新操作亭引,start_date保持不變,而end_date改為當(dāng)天皮获,也就是關(guān)鏈操作焙蚓;