程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 創新性應用 數據建模經驗談

創新性應用 數據建模經驗談

編輯:Oracle數據庫基礎
筆者從98年進入數據庫及數據倉庫領域工作至今已經有近八年的時間,對數據建模工作接觸的比較多,創新性不敢談,本文只是將工作中的經驗總結出來,供大家一同探討和指正。

  提起數據建模來,有一點是首先要強調的,數據建模師和DBA有著較大的不同,對數據建模師來說,對業務的深刻理解是第一位的,不同的建模方法和技巧是為業務需求來服務的。而本文則暫時拋開業務不談,主要關注於建模方法和技巧的經驗總結。

  從目前的數據庫及數據倉庫建模方法來說,主要分為四類。

  第一類是大家最為熟悉的關系數據庫的三范式建模,通常我們將三范式建模方法用於建立各種操作型數據庫系統。

  第二類是Inmon提倡的三范式數據倉庫建模,它和操作型數據庫系統的三范式建模在側重點上有些不同。Inmon的數據倉庫建模方法分為三層,第一層是實體關系層,也即企業的業務數據模型層,在這一層上和企業的操作型數據庫系統建模方法是相同的;第二層是數據項集層,在這一層的建模方法根據數據的產生頻率及訪問頻率等因素與企業的操作型數據庫系統的建模方法產生了不同;第三層物理層是第二層的具體實現。

  第三類是Kimball提倡的數據倉庫的維度建模,我們一般也稱之為星型結構建模,有時也加入一些雪花模型在裡面。維度建模是一種面向用戶需求的、容易理解的、訪問效率高的建模方法,也是筆者比較喜歡的一種建模方式。

  第四類是更為靈活的一種建模方式,通常用於後台的數據准備區,建模的方式不拘一格,以能滿足需要為目的,建好的表不對用戶提供接口,多為臨時表。

  下面簡單談談第四類建模方法的一些的經驗。

  數據准備區有一個最大的特點,就是不會直接面對用戶,所以對數據准備區中的表進行操作的人只有ETL工程師。ETL工程師可以自己來決定表中數據的范圍和數據的生命周期。下面舉兩個例子:

  1)數據范圍小的臨時表

  當需要整合或清洗的數據量過大時,我們可以建立同樣結構的臨時表,在臨時表中只保留我們需要處理的部分數據。這樣,不論是更新還是對表中某些項的計算都會效率提高很多。處理好的數據發送入准備加載到數據倉庫中的表中,最後一次性加載入數據倉庫。

  2)帶有冗余字段的臨時表

  由於數據准備區中的表只有自己使用,所以建立冗余字段可以起到很好的作用而不用承擔風險。

  舉例來說,筆者在項目中曾遇到這樣的需求,客戶表{客戶ID,客戶淨扣值},債項表{債項ID,客戶ID,債項余額,債項淨扣值},即客戶和債項是一對多的關系。其中,客戶淨扣值和債項余額已知,需要計算債項淨扣值。計算的規則是按債項余額的比例分配客戶的淨扣值。這時,我們可以給兩個表增加幾個冗余字段,如客戶表{客戶ID,客戶淨扣值,客戶余額},債項表{債項ID,客戶ID,債項余額,債項淨扣值,客戶余額,客戶淨扣值}。這樣通過三條SQL就可以直接完成整個計算過程。將債項余額匯總到客戶余額,將客戶余額和客戶淨扣值冗余到債項表中,在債項表中通過(債項余額×客戶淨扣值/客戶余額)公式即可直接計算處債項淨扣值。

  另外還有很多大家可以發揮的建表方式,如不需要主鍵的臨時表等等。總結來說,正因為數據准備區是不對用戶提供接口的,所以我們一定要利用好這一點,以給我們的數據處理工作帶來最大的便利為目的來進行數據准備區的表設計。

  行業借鑒經驗:

  數據倉庫架構經驗談

  對於數據倉庫的架構方法,不同的架構師有不同的原則和方法,筆者在這裡來總結一下當前常采用的架構方式及其優缺點。這些架構方式不限於某個行業,可以供各個行業借鑒使用。

  首先需要說明的一點是,目前在數據倉庫領域比較一致的意見是在數據倉庫中需要保留企業范圍內一致的原子層數據。而獨立的數據集市架構(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已經有了這個功能。畢竟技術方面復雜的事情留給廠商做是一個趨勢,而我們做應用的則更關注於業務。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved