2017計(jì)算機(jī)等考三級(jí)數(shù)據(jù)庫(kù)基礎(chǔ):創(chuàng)新性應(yīng)用數(shù)據(jù)建模經(jīng)驗(yàn)談

字號(hào):

  筆者從98年進(jìn)入數(shù)據(jù)庫(kù)及數(shù)據(jù)倉(cāng)庫(kù)領(lǐng)域工作至今已經(jīng)有近八年的時(shí)間,對(duì)數(shù)據(jù)建模工作接觸的比較多,創(chuàng)新性不敢談,本文只是將工作中的經(jīng)驗(yàn)總結(jié)出來,供大家一同探討和指正。   提起數(shù)據(jù)建模來,有一點(diǎn)是首先要強(qiáng)調(diào)的,數(shù)據(jù)建模師和DBA有著較大的不同,對(duì)數(shù)據(jù)建模師來說,對(duì)業(yè)務(wù)的深刻理解是第一位的,不同的建模方法和技巧是為業(yè)務(wù)需求來服務(wù)的。而本文則暫時(shí)拋開業(yè)務(wù)不談,主要關(guān)注于建模方法和技巧的經(jīng)驗(yàn)總結(jié)。   從目前的數(shù)據(jù)庫(kù)及數(shù)據(jù)倉(cāng)庫(kù)建模方法來說,主要分為四類。   第一類是大家最為熟悉的關(guān)系數(shù)據(jù)庫(kù)的三范式建模,通常我們將三范式建模方法用于建立各種操作型數(shù)據(jù)庫(kù)系統(tǒng)。   第二類是Inmon提倡的三范式數(shù)據(jù)倉(cāng)庫(kù)建模,它和操作型數(shù)據(jù)庫(kù)系統(tǒng)的三范式建模在側(cè)重點(diǎn)上有些不同。Inmon的數(shù)據(jù)倉(cāng)庫(kù)建模方法分為三層,第一層是實(shí)體關(guān)系層,也即企業(yè)的業(yè)務(wù)數(shù)據(jù)模型層,在這一層上和企業(yè)的操作型數(shù)據(jù)庫(kù)系統(tǒng)建模方法是相同的;第二層是數(shù)據(jù)項(xiàng)集層,在這一層的建模方法根據(jù)數(shù)據(jù)的產(chǎn)生頻率及訪問頻率等因素與企業(yè)的操作型數(shù)據(jù)庫(kù)系統(tǒng)的建模方法產(chǎn)生了不同;第三層物理層是第二層的具體實(shí)現(xiàn)。   第三類是Kimball提倡的數(shù)據(jù)倉(cāng)庫(kù)的維度建模,我們一般也稱之為星型結(jié)構(gòu)建模,有時(shí)也加入一些雪花模型在里面。維度建模是一種面向用戶需求的、容易理解的、訪問效率高的建模方法,也是筆者比較喜歡的一種建模方式。   第四類是更為靈活的一種建模方式,通常用于后臺(tái)的數(shù)據(jù)準(zhǔn)備區(qū),建模的方式不拘一格,以能滿足需要為目的,建好的表不對(duì)用戶提供接口,多為臨時(shí)表。   下面簡(jiǎn)單談?wù)劦谒念惤7椒ǖ囊恍┑慕?jīng)驗(yàn)。   數(shù)據(jù)準(zhǔn)備區(qū)有一個(gè)的特點(diǎn),就是不會(huì)直接面對(duì)用戶,所以對(duì)數(shù)據(jù)準(zhǔn)備區(qū)中的表進(jìn)行操作的人只有ETL工程師。ETL工程師可以自己來決定表中數(shù)據(jù)的范圍和數(shù)據(jù)的生命周期。下面舉兩個(gè)例子:   1)數(shù)據(jù)范圍小的臨時(shí)表   當(dāng)需要整合或清洗的數(shù)據(jù)量過大時(shí),我們可以建立同樣結(jié)構(gòu)的臨時(shí)表,在臨時(shí)表中只保留我們需要處理的部分?jǐn)?shù)據(jù)。這樣,不論是更新還是對(duì)表中某些項(xiàng)的計(jì)算都會(huì)效率提高很多。處理好的數(shù)據(jù)發(fā)送入準(zhǔn)備加載到數(shù)據(jù)倉(cāng)庫(kù)中的表中,最后一次性加載入數(shù)據(jù)倉(cāng)庫(kù)。   2)帶有冗余字段的臨時(shí)表   由于數(shù)據(jù)準(zhǔn)備區(qū)中的表只有自己使用,所以建立冗余字段可以起到很好的作用而不用承擔(dān)風(fēng)險(xiǎn)。   舉例來說,筆者在項(xiàng)目中曾遇到這樣的需求,客戶表{客戶ID,客戶凈扣值},債項(xiàng)表{債項(xiàng)ID,客戶ID,債項(xiàng)余額,債項(xiàng)凈扣值},即客戶和債項(xiàng)是一對(duì)多的關(guān)系。其中,客戶凈扣值和債項(xiàng)余額已知,需要計(jì)算債項(xiàng)凈扣值。計(jì)算的規(guī)則是按債項(xiàng)余額的比例分配客戶的凈扣值。這時(shí),我們可以給兩個(gè)表增加幾個(gè)冗余字段,如客戶表{客戶ID,客戶凈扣值,客戶余額},債項(xiàng)表{債項(xiàng)ID,客戶ID,債項(xiàng)余額,債項(xiàng)凈扣值,客戶余額,客戶凈扣值}。這樣通過三條SQL就可以直接完成整個(gè)計(jì)算過程。將債項(xiàng)余額匯總到客戶余額,將客戶余額和客戶凈扣值冗余到債項(xiàng)表中,在債項(xiàng)表中通過(債項(xiàng)余額×客戶凈扣值/客戶余額)公式即可直接計(jì)算處債項(xiàng)凈扣值。   另外還有很多大家可以發(fā)揮的建表方式,如不需要主鍵的臨時(shí)表等等??偨Y(jié)來說,正因?yàn)閿?shù)據(jù)準(zhǔn)備區(qū)是不對(duì)用戶提供接口的,所以我們一定要利用好這一點(diǎn),以給我們的數(shù)據(jù)處理工作帶來的便利為目的來進(jìn)行數(shù)據(jù)準(zhǔn)備區(qū)的表設(shè)計(jì)。   行業(yè)借鑒經(jīng)驗(yàn):   數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)經(jīng)驗(yàn)談   對(duì)于數(shù)據(jù)倉(cāng)庫(kù)的架構(gòu)方法,不同的架構(gòu)師有不同的原則和方法,筆者在這里來總結(jié)一下當(dāng)前常采用的架構(gòu)方式及其優(yōu)缺點(diǎn)。這些架構(gòu)方式不限于某個(gè)行業(yè),可以供各個(gè)行業(yè)借鑒使用。   首先需要說明的一點(diǎn)是,目前在數(shù)據(jù)倉(cāng)庫(kù)領(lǐng)域比較一致的意見是在數(shù)據(jù)倉(cāng)庫(kù)中需要保留企業(yè)范圍內(nèi)一致的原子層數(shù)據(jù)。而獨(dú)立的數(shù)據(jù)集市架構(gòu)(Independent data marts)沒有企業(yè)范圍內(nèi)一致的數(shù)據(jù),很可能會(huì)導(dǎo)致信息孤島的產(chǎn)生,除非在很小的企業(yè)內(nèi)或只針對(duì)固定主題,否則不建議建立這樣的架構(gòu)方式。聯(lián)邦式的數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)(Federated Data Warehouse Architecture)不管是在地域上的聯(lián)邦還是功能上的聯(lián)邦都需要先在不同平臺(tái)上建立各自的數(shù)據(jù)倉(cāng)庫(kù),再通過參考(reference)數(shù)據(jù)來實(shí)現(xiàn)整合,而這樣很容易造成整合的不徹底,除非聯(lián)邦式的數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)也采用Kimball的總線架構(gòu)(Bus Architecture)中類似的功能,即在數(shù)據(jù)準(zhǔn)備區(qū)保留一致性維度(Conformed Table)并不斷更新它。所以,這兩種架構(gòu)方式不在討論范圍之內(nèi)。下面主要討論剩下的三種架構(gòu)方式。   1)三范式(3NF)的原子層+數(shù)據(jù)集市   這樣的數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)的倡導(dǎo)者就是數(shù)據(jù)倉(cāng)庫(kù)之父Inmon,而他的企業(yè)信息工廠(Corporate Information System)就是典型的代表。這樣的架構(gòu)也稱之為企業(yè)數(shù)據(jù)倉(cāng)庫(kù)(Enterprise Data Warehouse,EDW)。企業(yè)信息工廠的實(shí)現(xiàn)方式是,首先進(jìn)行全企業(yè)的數(shù)據(jù)整合,建立企業(yè)信息模型,即EDW。對(duì)于各種分析需求再建立相應(yīng)的數(shù)據(jù)集市或者探索倉(cāng)庫(kù),其數(shù)據(jù)來源于EDW。三范式的原子層給建立OLAP帶來一定的復(fù)雜性,但是對(duì)于建立更復(fù)雜的應(yīng)用,如挖掘倉(cāng)庫(kù)、探索倉(cāng)庫(kù)提供了更好的支持。這類架構(gòu)的建設(shè)周期比較長(zhǎng),相應(yīng)的成本也比較高。   2)星型結(jié)構(gòu)(Star Schema)的原子層+HOLAP   星型結(jié)構(gòu)的倡導(dǎo)者是Kimall,他的總線架構(gòu)是該類架構(gòu)的典型代表??偩€架構(gòu)實(shí)現(xiàn)方式是,首先在數(shù)據(jù)準(zhǔn)備區(qū)中建立一致性維度、建立一致性事實(shí)的計(jì)算方法;其次在一致性維度、一致性事實(shí)的基礎(chǔ)上逐步建立數(shù)據(jù)集市。每次增加數(shù)據(jù)集市,都會(huì)在數(shù)據(jù)準(zhǔn)備區(qū)整合一致性維度,并將整合好的一致性維度同步更新到所有的數(shù)據(jù)集市。這樣,建立的所有數(shù)據(jù)集市合在一起就是一個(gè)整合好的數(shù)據(jù)倉(cāng)庫(kù)。正是因?yàn)榭偩€架構(gòu)這個(gè)可以逐步建立的特點(diǎn),它的開發(fā)周期比其他架構(gòu)方式的開發(fā)周期要短,相應(yīng)的成本也要低。在星型結(jié)構(gòu)的原子層上可以直接建立聚集,也可以建立HOLAP。筆者比較傾向于Kimball的星型結(jié)構(gòu)的原子層架構(gòu),在這種架構(gòu)中的經(jīng)驗(yàn)也比較多。   3)三范式(3NF)的原子層+ROLAP   這樣的數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)也稱為集中式架構(gòu)(Centralized Architecture),思路是在三范式的原子層上直接建立ROLAP,做的比較出色的就是MicroStrategy。在三范式的原子層上定義ROLAP比在星型結(jié)構(gòu)的原子層上定義ROLAP要復(fù)雜很多。采用這種架構(gòu)需要在定義ROLAP是多下些功夫,而且ROLAP的元數(shù)據(jù)不一定是通用的格式,所以對(duì)ROLAP做展現(xiàn)很可能會(huì)受到工具的局限。這類架構(gòu)和第一類很相似,只是少了原子層上的數(shù)據(jù)集市。   總結(jié)來說,這三種數(shù)據(jù)倉(cāng)庫(kù)的架構(gòu)方式都是不錯(cuò)的選擇。對(duì)于需要見效快、成本低的項(xiàng)目可以考慮采用第二種總線架構(gòu),對(duì)于資金充足并有成熟業(yè)務(wù)數(shù)據(jù)模型的企業(yè)可以考慮采用第一種架構(gòu)或第三種架構(gòu)。   應(yīng)用難點(diǎn)技巧:   變化數(shù)據(jù)捕獲經(jīng)驗(yàn)談   在數(shù)據(jù)倉(cāng)庫(kù)系統(tǒng)中,一個(gè)很重要的目的就是保留數(shù)據(jù)的歷史變化信息。而變化數(shù)據(jù)捕獲(Change Data Capture,CDC)就是為這個(gè)目的而產(chǎn)生的一項(xiàng)技術(shù)。變化數(shù)據(jù)捕獲常用的方法有:1)文件或者表的全掃描對(duì)比,2)DBMS日志獲取,3)在源系統(tǒng)中增加觸發(fā)器獲取,4)基于源系統(tǒng)的時(shí)間戳獲取,5)基于復(fù)制技術(shù)的獲取,6)DBMS提供的變化數(shù)據(jù)捕獲方法等。其中,由DBMS提供變化數(shù)據(jù)捕獲的方法是大勢(shì)所趨,即具體的捕獲過程由DBMS來完成。   像銀行、電信等很多行業(yè)的操作記錄生成后就不會(huì)改變,只有像客戶、產(chǎn)品等信息會(huì)隨時(shí)間發(fā)生緩慢的變化,所以通常的變化數(shù)據(jù)捕獲是針對(duì)維度表而言的。Kimball對(duì)緩慢變化維的分析及應(yīng)對(duì)策略基本上可以處理維度表的各種變化。   而對(duì)于一些零售行業(yè),像合同表中的合同金額類似的數(shù)值在錄入后是有可能會(huì)發(fā)生改變的,也就是說事實(shí)表的數(shù)據(jù)也有可能發(fā)生變化。通常對(duì)于事實(shí)表數(shù)據(jù)的修改屬于勘誤的范疇,可以采用類似緩慢變化維TYPE 1的處理方式直接更新事實(shí)表。筆者不太贊同對(duì)事實(shí)表的變化采用快照的方式插入一條新的事實(shí)勘誤記錄,這樣會(huì)給后續(xù)的展現(xiàn)、分析程序帶來太多的麻煩。   接下來要討論的是筆者曾經(jīng)遇到的一個(gè)頗為棘手的事實(shí)表數(shù)據(jù)改變的問題,該事實(shí)表的主鍵隨表中某些數(shù)據(jù)的變化發(fā)生改變。以其中的一個(gè)合同表為例,該合同表的主鍵是由“供貨單位編號(hào)”+“合同號(hào)”生成的智能主鍵,當(dāng)其中的“供貨單位編號(hào)”和“合同號(hào)”中任何一個(gè)發(fā)生變化時(shí),該合同表的主鍵都會(huì)發(fā)生變化,給變化數(shù)據(jù)捕獲帶來了很大的麻煩。   項(xiàng)目中,筆者的處理方式是采用觸發(fā)器的辦法來實(shí)現(xiàn)變化數(shù)據(jù)捕獲。具體的實(shí)現(xiàn)方式是:   1)建立一個(gè)新表作為保存捕獲的數(shù)據(jù)表使用,其中字段有“原主鍵”、“修改后主鍵”、及其他需要的字段,稱為“合同捕獲表”。   2)在原合同表Delete和Update時(shí)分別建立觸發(fā)器,當(dāng)刪除操作發(fā)生時(shí),建在Delete上的觸發(fā)器會(huì)插入一條記錄到“合同捕獲表”,其中“修改后主鍵”字段為空,表示該記錄是刪除的記錄;當(dāng)發(fā)生更新時(shí),將“原主鍵”、“修改后主鍵”及其他需要記錄的字段都保存入“合同捕獲表”中,表示該記錄被修改過,如果“原主鍵”和“修改后主鍵”不同,則表示主鍵被修改,如果相同,則表示主鍵沒有被修改。   3)由于操作系統(tǒng)中的主鍵通常會(huì)成為數(shù)據(jù)倉(cāng)庫(kù)中事實(shí)表的退化維度,可能仍會(huì)起主鍵的作用。所以在數(shù)據(jù)加載時(shí),需要分情況判斷“合同捕獲表”的數(shù)據(jù)來決定是否更新事實(shí)表中的退化維度。   可以說,這樣的基于觸發(fā)器的變化數(shù)據(jù)捕獲方法并不是一個(gè)很好的選擇。首先這需要對(duì)源系統(tǒng)有較大的權(quán)限;其次,觸發(fā)器會(huì)給源系統(tǒng)的性能帶來很大的影響。所以除非是沒有別的選擇,否則不建議采用這種方法。   而對(duì)于這樣的情況,我們?cè)诮⒉僮餍蛿?shù)據(jù)庫(kù)系統(tǒng)時(shí)完全可以避免。下面是對(duì)操作型數(shù)據(jù)庫(kù)系統(tǒng)建立者的幾點(diǎn)建議:1)操作型系統(tǒng)的主鍵不要建立成智能型的,至少不要建立成會(huì)變化的。2)操作型系統(tǒng)的表中需要加入操作人和操作時(shí)間字段,或者直接加入時(shí)間戳。3)操作型系統(tǒng)中操作型數(shù)據(jù)不要直接在原值上修改,可以采用“沖紅”的方式加入新的記錄。這樣后續(xù)建立數(shù)據(jù)倉(cāng)庫(kù)時(shí)就不需要考慮事實(shí)表數(shù)據(jù)的變化問題。   最后,期待各大數(shù)據(jù)庫(kù)管理系統(tǒng)的廠商能盡快在DBMS層提供功能強(qiáng)大、簡(jiǎn)單好用的變化數(shù)據(jù)捕獲功能,目前Oracle已經(jīng)有了這個(gè)功能。畢竟技術(shù)方面復(fù)雜的事情留給廠商做是一個(gè)趨勢(shì),而我們做應(yīng)用的則更關(guān)注于業(yè)務(wù)。