數(shù)倉 | Kimball的維度建模過時了嗎?
本文轉(zhuǎn)載自微信公眾號「大數(shù)據(jù)技術(shù)與數(shù)倉」,作者西貝。轉(zhuǎn)載本文請聯(lián)系大數(shù)據(jù)技術(shù)與數(shù)倉公眾號。
從20世紀80年代中期以來,kimball一直是數(shù)據(jù)倉庫和商業(yè)智能行業(yè)維度建模方法的思想開拓者。維度建模之初假設(shè)數(shù)據(jù)倉庫僅限于單服務(wù)器數(shù)據(jù)庫,隨著大數(shù)據(jù)時代的到來,分布式計算和分式存儲成為了新的趨勢,所以Ralph Kimball所普及的維度數(shù)據(jù)建模方法和技術(shù)需要一些修訂,這樣才能更好地滿足大數(shù)據(jù)建模的需求。需要注意的是,在數(shù)據(jù)倉庫領(lǐng)域, Inmon和Kimball是兩大主要陣營,但是Kimball的維度建模理論對于現(xiàn)代數(shù)倉建設(shè)的影響可謂是非常深遠的,所以本文主要討論維度建模的相關(guān)問題。
不要使用代理鍵
在KimBall的維度建模中,必須使用代理鍵作為每個維表的主鍵,用于處理緩慢變化維。
這個問題對于初學數(shù)倉維度建模的人而言,很容易陷入Kimball提出的代理鍵的漩渦之中,以至于把時間都浪費了。其實代理鍵在大數(shù)據(jù)倉庫環(huán)境下顯得很不合時宜,并且很難維護。在實際的建模中使用自然鍵是一個很好的選擇,如果維度有一個復合主鍵,只需將它們與合理的分隔符連接在一起,即可根據(jù)多個自然鍵生成單個鍵。
總結(jié)下來不使用代理鍵主要有一下兩個原因:
- 分布式計算系統(tǒng),淡化了事務(wù)的概念,生成代理鍵的代價會很高
- 代理鍵會大大增加ETL的復雜性,對于ETL任務(wù)的開發(fā)和維護成本很高
避免使用 Type-2 SCD
緩慢變化維是維度建模理論的一個非常重要的概念,大多數(shù)情況下,Type-0 或 Type-1 SCD 可以解決問題。除非有特別關(guān)鍵的原因,否則我會避免使用 Type-2 SCD。尤其是在大數(shù)據(jù)環(huán)境下的數(shù)據(jù)建模,幾乎很少使用Type-2 SCD。
關(guān)于SCD的解釋如下:
- SCD1:通過更新維度記錄直接覆蓋已存在的值,它不維護記錄的歷史。SCD1一般用于修改錯誤的數(shù)據(jù)。
- SCD2:在源數(shù)據(jù)發(fā)生變化時,給維度記錄建立一個新的“版本”記錄,從而維護維度歷史。SCD2不刪除、修改已存在的數(shù)據(jù)。
- SCD3:通常用作保持維度記錄的幾個版本。它通過給某個數(shù)據(jù)單元增加多個列來維護歷史。例如,為了記錄客戶地址的變化,customer_dim維度表有一個 customer_address列和一個previous_customer_address列,分別記錄當前和上一個版本的地址。SCD3可以有效維護有限的歷史,而不像SCD2那樣保存全部歷史。SCD3 很少使用。它只適用于數(shù)據(jù)的存儲空間不足并且用戶接受有限維度歷史的情況。
如果非得需要實現(xiàn) Type-2 SCD(不建議使用),也不要使用代理鍵。相反,將自然鍵與表示 SCD 中的有效日期和到期日期字段結(jié)合使用。這只是查詢稍微復雜一點,但更靈活,更容易實現(xiàn),并且避免了對代理鍵的需要。
維表快照
在關(guān)系型數(shù)據(jù)倉庫時代,快照維度顯得沒有意義,但在大數(shù)據(jù)環(huán)境中卻非常有意義。簡單將就是使用分區(qū)表,每個分區(qū)內(nèi)存儲的是截止當前時間的全量維度信息。
通過快照的方式處理緩慢變化維,是在大數(shù)據(jù)環(huán)境的數(shù)據(jù)倉庫實踐中常用的方式。以離線數(shù)倉為例,計算周期一般是每天一次,基于此周期,處理緩慢變化維的方式就是每天保留一份全量的快照數(shù)據(jù)。以商品維度為例,就是每天保留一份全量的商品快照數(shù)據(jù)。在下游的使用過程中,可以獲取每天的維度信息,使用起來非常方便。
優(yōu)點
- 簡單,開發(fā)和維護成本低
- 方便,很容易理解,下游使用數(shù)據(jù)時只需要限定所需要的日期即可
缺點
- 存儲浪費
- 綜合看來,由于存儲成本遠低于CPU、內(nèi)存的成本,此方法是犧牲存儲獲取ETL效率優(yōu)化和邏輯上的簡單,顯然是利大于弊的。
數(shù)據(jù)建模的非規(guī)范化
所謂的非規(guī)范化,即是將某些維度屬性冗余至事實表。過去之所以不贊成這樣做,部分原因是因為 RDBMS 將數(shù)據(jù)存儲在表中的方式。隨著 Parquet 和 ORC 等列式數(shù)據(jù)存儲格式的出現(xiàn);這不再是一個大問題。
在傳統(tǒng)的維度建模的星型模型中,對于維度的處理是將其單獨存放在專門的維表中,然后通過事實表的外鍵獲取維度。這樣做的目的是為了減少事實表的冗余,從而減少存儲消耗。
但是在大數(shù)據(jù)背景下,考慮到提高下游任務(wù)的使用效率,降低獲取數(shù)據(jù)的復雜性,減少關(guān)聯(lián)表的數(shù)量,通常的做法是將常用的維度冗余至事實表中。
善于使用復雜的數(shù)據(jù)類型
通常,作為數(shù)據(jù)工程師,我們的工作是將非結(jié)構(gòu)化數(shù)據(jù)集重新組織為結(jié)構(gòu)化(或半結(jié)構(gòu)化)數(shù)據(jù)集,但是在一些場景下,非結(jié)構(gòu)化是一個很好的選擇。
復雜的數(shù)據(jù)類型違反了最重要的范式(原子列)規(guī)則,其實你會發(fā)現(xiàn),維度數(shù)據(jù)建模的許多傳統(tǒng)理論都違反了其中的一些規(guī)則。由于復雜數(shù)據(jù)類型使用起來非常靈活,其在現(xiàn)代數(shù)據(jù)倉庫中功能是非常強大的。
當某個實體的詳細信息在不久的將來發(fā)生變化時,使用一個 JSON來保存這些字段是很有必要的,直到schema的細節(jié)可以固化。
對于一對多的情況,使用數(shù)組或許是一個很好的方案,例如,如果在商品維度中存儲一些標簽字段,我們就可以將這些字段存在在一個數(shù)組字段中,而不是將標簽存儲在 一張標簽表中。
值得注意的是,對于一些特殊的場景,要善于使用復雜類型,而不是濫用復雜數(shù)據(jù)類型。結(jié)構(gòu)化依然是建模過程中需要考慮的重點。
總結(jié)
Ralph Kimball的維度建模理論對于當今數(shù)據(jù)倉庫建模的影響可謂是非常深遠的,我們現(xiàn)在主流的數(shù)倉建模都是基于維度建模的。隨著大數(shù)據(jù)技術(shù)的不斷發(fā)展,維度建模的一些方法需求隨之做出一些調(diào)整,但是其核心思想是不變的。另外,作為數(shù)倉開發(fā)者,我們要遵循一個準則:數(shù)據(jù)倉庫的設(shè)計是為了業(yè)務(wù)服務(wù)的,是為了發(fā)揮數(shù)據(jù)運營的優(yōu)勢而存在的,所以彰顯數(shù)據(jù)價值,賦能業(yè)務(wù)增長才是我們需要考慮的最根本問題。