行業借鑒經驗:
數據倉庫架構經驗談
對於數據倉庫的架構方法,不同的架構師有不同的原則和方法,筆者在這裡來總結一下當前常采用的架構方式及其優缺點。這些架構方式不限於某個行業,可以供各個行業借鑒使用。
首先需要說明的一點是,目前在數據倉庫領域比較一致的意見是在數據倉庫中需要保留企業范圍內一致的原子層數據。而獨立的數據集市架構(Independent data marts)沒有企業范圍內一致的數據,很可能會導致信息孤島的產生,除非在很小的企業內或只針對固定主題,否則不建議建立這樣的架構方式。聯邦式的數據倉庫架構(Federated Data Warehouse Architecture)不管是在地域上的聯邦還是功能上的聯邦都需要先在不同平台上建立各自的數據倉庫,再通過參考(reference)數據來實現整合,而這樣很容易造成整合的不徹底,除非聯邦式的數據倉庫架構也采用Kimball的總線架構(Bus Architecture)中類似的功能,即在數據准備區保留一致性維度(Conformed Table)並不斷更新它。所以,這兩種架構方式不在討論范圍之內。下面主要討論剩下的三種架構方式。
1)三范式(3NF)的原子層+數據集市
這樣的數據倉庫架構最大的倡導者就是數據倉庫之父Inmon,而他的企業信息工廠(Corporate Information System)就是典型的代表。這樣的架構也稱之為企業數據倉庫(Enterprise Data Warehouse,EDW)。企業信息工廠的實現方式是,首先進行全企業的數據整合,建立企業信息模型,即EDW。對於各種分析需求再建立相應的數據集市或者探索倉庫,其數據來源於EDW。三范式的原子層給建立OLAP帶來一定的復雜性,但是對於建立更復雜的應用,如挖掘倉庫、探索倉庫提供了更好的支持。這類架構的建設周期比較長,相應的成本也比較高。
2)星型結構(Star Schema)的原子層+HOLAP
星型結構最大的倡導者是Kimall,他的總線架構是該類架構的典型代表。總線架構實現方式是,首先在數據准備區中建立一致性維度、建立一致性事實的計算方法;其次在一致性維度、一致性事實的基礎上逐步建立數據集市。每次增加數據集市,都會在數據准備區整合一致性維度,並將整合好的一致性維度同步更新到所有的數據集市。這樣,建立的所有數據集市合在一起就是一個整合好的數據倉庫。正是因為總線架構這個可以逐步建立的特點,它的開發周期比其他架構方式的開發周期要短,相應的成本也要低。在星型結構的原子層上可以直接建立聚集,也可以建立HOLAP。筆者比較傾向於Kimball的星型結構的原子層架構,在這種架構中的經驗也比較多。
3)三范式(3NF)的原子層+ROLAP
這樣的數據倉庫架構也稱為集中式架構(Centralized Architecture),思路是在三范式的原子層上直接建立ROLAP,做的比較出色的就是MicroStrategy。在三范式的原子層上定義ROLAP比在星型結構的原子層上定義ROLAP要復雜很多。采用這種架構需要在定義ROLAP是多下些功夫,而且ROLAP的元數據不一定是通用的格式,所以對ROLAP做展現很可能會受到工具的局限。這類架構和第一類很相似,只是少了原子層上的數據集市。
總結來說,這三種數據倉庫的架構方式都是不錯的選擇。對於需要見效快、成本低的項目可以考慮采用第二種總線架構,對於資金充足並有成熟業務數據模型的企業可以考慮采用第一種架構或第三種架構。
應用難點技巧:
變化數據捕獲經驗談
在數據倉庫系統中,一個很重要的目的就是保留數據的歷史變化信息。而變化數據捕獲(Change Data Capture,CDC)就是為這個目的而產生的一項技術。變化數據捕獲常用的方法有:1)文件或者表的全掃描對比,2)DBMS日志獲取,3)在源系統中增加觸發器獲取,4)基於源系統的時間戳獲取,5)基於復制技術的獲取,6)DBMS提供的變化數據捕獲方法等。其中,由DBMS提供變化數據捕獲的方法是大勢所趨,即具體的捕獲過程由DBMS來完成。
像銀行、電信等很多行業的操作記錄生成後就不會改變,只有像客戶、產品等信息會隨時間發生緩慢的變化,所以通常的變化數據捕獲是針對維度表而言的。Kimball對緩慢變化維的分析及應對策略基本上可以處理維度表的各種變化。
而對於一些零售行業,像合同表中的合同金額類似的數值在錄入後是有可能會發生改變的,也就是說事實表的數據也有可能發生變化。通常對於事實表數據的修改屬於勘誤的范疇,可以采用類似緩慢變化維TYPE 1的處理方式直接更新事實表。筆者不太贊同對事實表的變化采用快照的方式插入一條新的事實勘誤記錄,這樣會給後續的展現、分析程序帶來太多的麻煩。
接下來要討論的是筆者曾經遇到的一個頗為棘手的事實表數據改變的問題,該事實表的主鍵隨表中某些數據的變化發生改變。以其中的一個合同表為例,該合同表的主鍵是由“供貨單位編號”+“合同號”生成的智能主鍵,當其中的“供貨單位編號”和“合同號”中任何一個發生變化時,該合同表的主鍵都會發生變化,給變化數據捕獲帶來了很大的麻煩。
項目中,筆者的處理方式是采用觸發器的辦法來實現變化數據捕獲。具體的實現方式是:
1)建立一個新表作為保存捕獲的數據表使用,其中字段有“原主鍵”、“修改後主鍵”、及其他需要的字段,稱為“合同捕獲表”。
2)在原合同表Delete和Update時分別建立觸發器,當刪除操作發生時,建在Delete上的觸發器會插入一條記錄到“合同捕獲表”,其中“修改後主鍵”字段為空,表示該記錄是刪除的記錄;當發生更新時,將“原主鍵”、“修改後主鍵”及其他需要記錄的字段都保存入“合同捕獲表”中,表示該記錄被修改過,如果“原主鍵”和“修改後主鍵”不同,則表示主鍵被修改,如果相同,則表示主鍵沒有被修改。
3)由於操作系統中的主鍵通常會成為數據倉庫中事實表的退化維度,可能仍會起主鍵的作用。所以在數據加載時,需要分情況判斷“合同捕獲表”的數據來決定是否更新事實表中的退化維度。
可以說,這樣的基於觸發器的變化數據捕獲方法並不是一個很好的選擇。首先這需要對源系統有較大的權限;其次,觸發器會給源系統的性能帶來很大的影響。所以除非是沒有別的選擇,否則不建議采用這種方法。
而對於這樣的情況,我們在建立操作型數據庫系統時完全可以避免。下面是對操作型數據庫系統建立者的幾點建議:1)操作型系統的主鍵不要建立成智能型的,至少不要建立成會變化的。2)操作型系統的表中需要加入操作人和操作時間字段,或者直接加入時間戳。3)操作型系統中操作型數據最好不要直接在原值上修改,可以采用“沖紅”的方式加入新的記錄。這樣後續建立數據倉庫時就不需要考慮事實表數據的變化問題。
最後,期待各大數據庫管理系統的廠商能盡快在DBMS層提供功能強大、簡單好用的變化數據捕獲功能,目前Oracle已經有了這個功能。畢竟技術方面復雜的事情留給廠商做是一個趨勢,而我們做應用的則更關注於業務。