本文中圖片引用自:https://blog.csdn.net/houfengfei668/article/details/79619215,文章中還提到了相應(yīng)的全量增量圖,我沒(méi)有貼過(guò)來(lái)。
拉鏈表的定義以及適用場(chǎng)景
1.1定義
拉鏈表是針對(duì)數(shù)據(jù)倉(cāng)庫(kù)設(shè)計(jì)中表存儲(chǔ)數(shù)據(jù)的方式而定義的,顧名思義,所謂拉鏈,就是記錄歷史。記錄一個(gè)事物從開(kāi)始,一直到當(dāng)前狀態(tài)的所有變化的信息。
1.2 適用場(chǎng)景
給出以下一個(gè)應(yīng)用場(chǎng)景
- 有一些表的數(shù)據(jù)量很大,比如一張用戶表,大約10億條記錄,50個(gè)字段,這種表,即使使用ORC壓縮,單張表的存儲(chǔ)也會(huì)超過(guò)100G,在HDFS使用雙備份或者三備份的話就更大一些。
- 表中的部分字段會(huì)被update更新操作,如用戶聯(lián)系方式,產(chǎn)品的描述信息,訂單的狀態(tài)等等。
- 需要查看某一個(gè)時(shí)間點(diǎn)或者時(shí)間段的歷史快照信息,比如,查看某一個(gè)訂單在歷史某一個(gè)時(shí)間點(diǎn)的狀態(tài)。
- 表中的記錄變化的比例和頻率不是很大,比如,總共有10億的用戶,每天新增和發(fā)生變化的有200萬(wàn)左右,變化的比例占的很小。
若不使用拉鏈表,解決方案此處給出兩種:
- 方案一:每天只留最新的一份,比如我們每天抽取最新的一份全量數(shù)據(jù)到Hive中。(占無(wú)法查看歷史數(shù)據(jù))
- 方案二:每天保留一份全量的切片數(shù)據(jù)。(存儲(chǔ)空間占用量大,無(wú)法確定數(shù)據(jù)生命周期,保留多少份全量無(wú)法控制)
此時(shí)可以考慮使用拉鏈表。首先它在空間上做了一個(gè)取舍,雖說(shuō)不像方案一那樣占用量那么小,但是它每日的增量可能只有方案二的千分之一甚至是萬(wàn)分之一。其次它能滿足方案二所能滿足的需求,既能獲取最新的數(shù)據(jù),也能添加篩選條件也獲取歷史的數(shù)據(jù)。
拉鏈表的算法
很多博客上介紹了拉鏈表當(dāng)有更新數(shù)據(jù)時(shí),采用的算法。本文給出一張更新過(guò)程的圖與算法過(guò)程相結(jié)合,簡(jiǎn)要介紹拉鏈表的存儲(chǔ)更新情況。
算法:
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)鏈操作
根據(jù)上述算法說(shuō)明,下面給出操作的過(guò)程圖:


拉鏈表操作例子
注釋:
- 開(kāi)始結(jié)束時(shí)間表示該條記錄的生命周期時(shí)間
- 結(jié)束時(shí)間為 ‘2999-12-31’表示該條記錄目前處于有效狀態(tài)。
- 如果查詢當(dāng)前所有有效的記錄,則
select * from user where end_date = ‘2999-12-31’ - 如果查詢2017-08-01的歷史快照,則select * from user where start_date <= ‘2017-08-01’ and t_end_date >= ‘2017-08-01。\
關(guān)于hive中,數(shù)據(jù)拉鏈的實(shí)現(xiàn),推薦一篇很好的文章:https://blog.csdn.net/zhaodedong/article/details/54177686