鏈: 古代軟兵器的中介之物,故名思意.有着連接、銜接的意思.拉鏈算法是目前數據倉庫領域比較XX的算法之一..通用非常廣.記錄數據量很大且為全量實體記錄 歷史的操作。例如,某某移動通信公司客戶資料,以河北為例,河北有客戶2800W,客戶資料每個一條就是2800W條記錄算上歷史客戶,全量大概有 5000W條左右。作為數據倉庫來存儲這些信息幾千萬條記錄不算什么。可是要是記錄歷史全量所用到的存儲就非常的龐大。問題實例為:一般正常情況下,從河 北移動的BOSS系統上每天采集全量的日數據大概為2500W條,歷史存儲每天存儲一個2500W條的日表,存儲三個月,就需要3*30*2500W條的 數據存儲空間,數據量為20E。這只是存儲三個月的歷史如果存儲更長時間則無法估計需要的存儲。而用拉鏈算法存儲。每日只是向歷史表(HIS)中添加新增 和變化的數據量。每日不過數十W條。存儲一年也就是需要5000W條記錄的存儲空間即兩個日全量的空間。下面詳細介紹下拉鏈算法:
1.采集當日全量存儲到 ND(NewDay) 表中。(比正常的全量表多兩個字段(START_DATE&END_DATE))
2.可從歷史表中取出昨日全量數據存儲到 OD(OldDay)表中。(比正常的全量表多兩個字段(START_DATE&END_DATE))
3.用ND-OD為當日新增和變化的數據(即每日增量)。
4.用OD-ND為狀態到此結束需要封鏈的數據。
5.歷史表(HIS)比ND表和OD表多兩個字段(START_DATE&END_DATE)
6.針對第三部來講,ND和OD表的(START_DATE&END_DATE)分別記錄當前日期和最大日期,取意為開始日期為當前天的數據和結束日期為最大日期。注意OD和ND的START_DATEND——OD兩個表進行全字段比較但是(START_DATE&END_DATE)除外。將結果記錄到W_I表中OD——ND兩個表進行全字段比較同樣(START_DATE&END_DATE)除外。將結果記錄到W_U表中
7.將W_I表的內容全部插入到HIS表中。
8.對歷史表(HIS)和OD表比較對歷史表最更新操作即在歷史表(HIS)中數據進行更新操作以W_U表為准,即對歷史表與W_U比對 (START_DATE&END_DATE除外),在歷史表(HIS)中也在W_U表中的數據將其END_DATE改成當前天,說明該記錄對當前 天失效。
9。取數據時候對日期進行條件選擇即可如:取20080101日的數據條件部分為(where start-date<=’20080101′ and end_date>20070801 ),即可全部SQL為:(select * from table(his) where start-date<=’20080101′ and end_date>20070801 )
表結構設計之拉鏈表
(一)概念
拉鏈表是針對數據倉庫設計中表存儲數據的方式而定義的,顧名思義,所謂拉鏈,就是記錄歷史。記錄一個事物從開始,一直到當前狀態的所有變化的信息。
在歷史表中對客戶的一生的記錄可能就這樣幾條記錄,避免了按每一天記錄客戶狀態造成的海量存儲的問題:
(NAME)人名 (START-DATE)開始日期 (END-DT)結束日期 (STAT)狀態
client 19000101 19070901 H在家
client 19070901 19130901 A小學
client 19130901 19160901 B初中
client 19160901 19190901 C高中
client 19190901 19230901 D大學
client 19230901 19601231 E公司
client 19601231 29991231 H退休在家
上面的每一條記錄都是不算末尾的,比如到19070901,client已經在A,而不是H了。所以除最后一條記錄因為狀態到目前都未改變的,其余的記錄實際上在END-DT那天,都不在是該條記錄END-DT那天的狀態。這種現象可以理解為算頭不算尾。
(二)算法
1采集當日全量數據到ND(NewDay)表;
2可從歷史表中取出昨日全量數據存儲到OD(OldDay)表;
3(ND-OD)就是當日新增和變化的數據,也就是當天的增量,用W_I表示;
4(OD-ND)為狀態到此結束需要封鏈的數據,用W_U表示;
5將W_I表的內容全部插入到歷史表中,這些是新增記錄,start_date為當天,而end_date為max值;
6對歷史表進行W_U部份的更新操作,start_date保持不變,而end_date改為當天,也就是關鏈操作;
拉鏈表 實際上是一個數據的有效 更新處理方法。 在定義了對於該方法支持的幾個字段后可以對數據進行處理。
講解一個加了幾個字段的的一種處理方法
模擬場景 ;
1.定義兩個臨時表,
一個為當日全量數據,另一個為需要新增或更新的數據;
CREATE TABLE A_day_full ;
CREATE TABLE B ;
2獲取當日全量數據
INSERT INTO A SELECT (a,b,c,cur_date, max_date) FROM SOURCE_Table
3抽取新增或有變化的數據,從 A 臨時表到B 臨時表;
INSERT INTO B
SELECT fieldname FROM A
WHERE NOT IN (select fieldname from A_HIS where end_date=’max_date’);
4更新歷史表的失效記錄的end_date為max值
UPDATE A1 FROM a_his A1, B A2
SET End_Date=’current_date’
WHERE A1.xx=A2.xx AND A1.End_Date=’max_date’;
5將新增或者有變化的數據插入目標表*/
INSERT INTO A_HIS SELECT * FROM B ;