上一篇我們了解了OLTP和OLAP數(shù)據(jù)處理類型。OLTP處理的是關(guān)系模型表即實體-關(guān)系表ER,而OLAP處理的是維度模型表。
數(shù)倉(一)簡介數(shù)倉,OLTP和OLAP
本篇我們來討論一下數(shù)倉中兩種建模的方式:關(guān)系建模和維度建模,特別是維度建模的4個步驟,是數(shù)倉領(lǐng)域核心重要內(nèi)容,及數(shù)倉分層。
數(shù)據(jù)模型就是數(shù)據(jù)組織和存儲方法,它強調(diào)從業(yè)務(wù)、數(shù)據(jù)存取和使用角度合理存儲數(shù)據(jù)。Linux的創(chuàng)始人Torvalds有一段關(guān)于“什么才是優(yōu)秀程序員”的話:“爛程序員關(guān)心的是代碼,好程序員關(guān)心的是數(shù)據(jù)結(jié)構(gòu)和它們之間的關(guān)系”。
只有數(shù)據(jù)模型將數(shù)據(jù)有序的組織和存儲起來之后,數(shù)據(jù)才能得到高性能、低成本、高效率、高質(zhì)量的使用。關(guān)于數(shù)倉的建模有兩種基本的模型:關(guān)系建模是數(shù)據(jù)倉庫之父Inmon推崇的、從全企業(yè)的高度設(shè)計一個3NF模型的方法,用實體加關(guān)系描述的數(shù)據(jù)模型描述企業(yè)和業(yè)務(wù)架構(gòu)。在范式理論上符合3NF,站在企業(yè)角度面向主題的抽象,而不是針對某個具體業(yè)務(wù)流程的實體對象關(guān)系抽象。它更多是面向數(shù)據(jù)的整合和一致性治理,正如Inmon所希望達到的“single version of the truth”。是數(shù)據(jù)倉庫領(lǐng)域另一位大師Ralph Kimball 所倡導的。維度建模以分析決策的需求出發(fā)構(gòu)建模型,構(gòu)建的數(shù)據(jù)模型為分析需求服務(wù),因此它重點解決用戶如何更快速完成分析需求,同時還有較好的大規(guī)模復雜查詢的響應(yīng)性能,更直接面向業(yè)務(wù)。為什么維度建模是數(shù)據(jù)倉庫/商業(yè)智能 項目成功的關(guān)鍵?因為不管我們的數(shù)據(jù)量從GB到TG還是到PB,雖然數(shù)據(jù)量越來越大,但是數(shù)據(jù)展現(xiàn)要獲得成功,就必須建立在簡單性的基礎(chǔ)之上,而維度建模就是時刻考慮如何能夠提供簡單性,以業(yè)務(wù)為驅(qū)動,以用戶理解性和查詢性能為目標。
維度模型分為:事實表和維度表;
我們看下面這個維度模型示意圖:
紅框:事實表SalesOrder
綠色圓形框:維度表Gender、Date、Product等

事實表(Fact Table)用來記錄具體事件,包含了每個事件的具體要素,以及具體發(fā)生的事情。事實表是主干,簡明扼要的介紹一個事實。上圖事實表例子中就通過一條事實表記錄:說明了某個地方(LocationId)的某人(用戶CustomerId)在某個時間(時間DateId)買了某產(chǎn)品(產(chǎn)品ProductId)金額SalesAmount等。- 每一個事實表的行包括具有可加性的數(shù)值型的度量值;
- 與維表相連接的外鍵,通常具有兩個和兩個以上的外鍵;
- 內(nèi)容相對的窄即列數(shù)較少(主要是外鍵id和度量值)
- 經(jīng)常發(fā)生變化,每天會新增加很多
事實表又分為以下六類
1.1、事務(wù)型事實表
以每個事務(wù)或事件為單位,例如一個銷售訂單記錄,一筆支付記錄等,作為事實表里的一行數(shù)據(jù)。一旦事務(wù)被提交,事實表數(shù)據(jù)被插入,數(shù)據(jù)就不再進行更改,其更新方式為增量更新。周期型快照事實表,表中不會保留所有數(shù)據(jù),只保留固定時間間隔的數(shù)據(jù),例如每天或者 每月的銷售額或每月的賬戶余額等。例如購物車,有加減商品,隨時都有可能變化,但是我們更關(guān)心每天結(jié)束時這里面有多少商品,方便我們后期統(tǒng)計分析。累計快照事實表用于跟蹤業(yè)務(wù)事實的變化。例如,數(shù)據(jù)倉庫中可能需要累積或者存儲 訂單從下訂單開始,到訂單商品被打包、運輸、和簽收的各個業(yè)務(wù)階段的時間點數(shù)據(jù)來跟蹤 訂單聲明周期的進展情況。當這個業(yè)務(wù)過程進行時,事實表的記錄也要不斷更新。
1.4、累無事實的事實表
我們以上討論的事實表度量都是數(shù)字化的,當然實際應(yīng)用中絕大多數(shù)都是數(shù)字化的度量,但是也可能會有少量的沒有數(shù)字化的值但是還很有價值的字段,無事實的事實表就是為這種數(shù)據(jù)準備的,利用這種事實表可以分析發(fā)生了什么。聚集,就是對原子粒度的數(shù)據(jù)進行簡單的聚合操作,目的就是為了提高查詢性能。如我們需求是查詢?nèi)珖兄械睦碡斂備N售額,我們原子粒度的事實表中每行是每個支行每個商品的銷售額,聚集事實表就可以先聚合每個支行的總銷售額,這樣匯總所有支行的銷售額時計算的數(shù)據(jù)量就會小很多。1.6、合并事實表
這種事實表遵循一個原則,就是相同粒度,數(shù)據(jù)可以來自多個過程,但是只要它們屬于相同粒度,就可以合并為一個事實表,這類事實表特別適合經(jīng)常需要共同分析的多過程度量。維度表(Dimension Table )一般是對事實的描述信息。每一張維度表對應(yīng)現(xiàn)實世界中的一個對象或者概念。例如:用戶、商品、日期、地區(qū)等。是依賴事實表而存在的,沒有事實表數(shù)據(jù),維度表也就沒有存在的意義。每個維度表都是對事實表中的每個列/字段進行展開描述。比如:事實表中的用戶ID,就可以進一步展開成一張維度表,記錄該用戶ID實體的用戶名、聯(lián)系信息、地址信息、年齡、性別和注冊方式等等。一般來說,對于數(shù)倉,事實表的增刪改操作相比維度表更為頻繁,模型建立后,維度表中的數(shù)據(jù)保持相對穩(wěn)定。- 跟事實表相比,行數(shù)相對較?。?/span>
- 內(nèi)容相對固定:編碼表。比如:城市行政編碼表等
通過事實表和維度表組織起來的數(shù)倉多維數(shù)據(jù)模型,相比原本分散在數(shù)據(jù)庫等各處的數(shù)據(jù),能夠有更有目的更高效的查詢效率。比如可以查詢匯總地域維度中某個省的商品銷售情況,也可以通過時間維度分析每個季度的某類商品銷售趨勢。將多個維度表跟事實表進行不同程度的連接,可以展開得到各種各樣的分析結(jié)果,滿足商品運營等數(shù)據(jù)使用者的不同需求。
在建模的基礎(chǔ)上又分為常見的三種模型:星型模型、雪花模型、星座模型。
1、星型模型(Star Schema)
星形模式(Star Schema)是最常用的維度建模方式。一般星形模式的維度建模由一個事實表(SalesFactTable)和一組維度表(time、branch、item、location等)成。- 維度表只和事實表關(guān)聯(lián),維度表之間沒有關(guān)聯(lián);
- 每個維度表的主鍵為單列,且該主鍵放置在事實表中,作為兩邊連接的邏輯外鍵;
每個維度都有一個維作為主鍵,所有這些維度表主鍵組合成事實表的主鍵。強調(diào)的是對維度進行預(yù)處理,將多個維度集合到一個事實表,形成一個寬表。這也是我們在使用比如:hive時,經(jīng)常會看到一些大寬表的原因,大寬表一般都是事實表,包含了維度關(guān)聯(lián)的主鍵和一些度量信息,而維度表則是事實表里面維度的具體信息,使用時候一般通過join來組合數(shù)據(jù),相對來說對OLAP的分析比較方便。
2、雪花模型((Snowflake Schema)
雪花模式(Snowflake Schema)當有一個或多個維度表沒有直接連接到事實表上,而是通過其他維度表連接到事實表上時,稱雪花模型。每個維度表可繼續(xù)向外連接多個子維度表。(三范式代表作)
比如:這里SalFactTable是事實表,location作為一維維度表,city是二維維度表

雪花模型是對星型模型的擴展。它對星型模型的維表進一步層次化,原有的各維表可能被擴展為小的事實表,形成一些局部的 “層次 ” 區(qū)域,這些被分解的表都連接到主維度表而不是事實表。
星形模式中的維度表相對雪花模式來說要大,而且不滿足規(guī)范化設(shè)計。雪花模型相當于將星形模式的大維表拆分成小維表,滿足了規(guī)范化設(shè)計。
雪花模型更加符合數(shù)據(jù)庫范式,減少數(shù)據(jù)冗余,但是在分析數(shù)據(jù)的時候,操作比較復雜,需要join的表比較多所以其性能并不一定比星型模型高。
雪花模型和星型模型的區(qū)別:
在于維度的層級,標準的星型模型維度只有一層,而雪花模型涉及多層維度
然而這種模式在實際應(yīng)用中很少見,因為這樣做會導致開發(fā)難度增大因為join太多,hadoop體系會增加資源開銷,而數(shù)據(jù)冗余問題在數(shù)據(jù)倉庫里并不嚴重。
3、星座模型(Fact Constellations Schema)
星座模式(Fact Constellations Schema)也是星型模式的擴展。前面兩種維度建模方法都是多維表對應(yīng)單事實表,但在很多時候維度空間內(nèi)的事實表不止一個,而一個維度表也可能被多個事實表用到。

星座模型和星型、雪花型模型區(qū)別:
主要在于事實表的數(shù)量,星型和雪花型一般是基于1個事實表,而星座模型是基于多個事實表。
在實際業(yè)務(wù)開發(fā)中,因為數(shù)倉有海量多個事實表的,并且會共享一些維度,不會選擇單一的一種模型,會多個模型混合是常態(tài)。單一層維度和多層維度并存。星座模式將作為最主要的維度建模。但是總體上需要注意的是要盡量減少星型模型的維度,因為hadoop體系,減少join就意味著減少shuffle,減少資源。
我們知道事實表,維度表,星形模型,雪花模型、星座模型這些概念了,但是實際業(yè)務(wù)中,我們怎么根據(jù)海量的業(yè)務(wù)數(shù)據(jù)進行數(shù)倉建設(shè)呢?根據(jù)《數(shù)倉工具箱》書中的維度建模四步:維度建模必須以業(yè)務(wù)為根基進行建模,那么選擇業(yè)務(wù)過程,就是在整個業(yè)務(wù)流程中選取我們需要建模的業(yè)務(wù),根據(jù)公司業(yè)務(wù)提供的需求及日后的易擴展性等進行選擇業(yè)務(wù)。比如:銀行理財業(yè)務(wù),整個理財業(yè)務(wù)有幾十種產(chǎn)品,每種不通同的產(chǎn)品期限不一致,募集期不一樣,有些是手機客戶端可以購買,有些事現(xiàn)場雙錄才能購買,有些是私行購買,有些事個人達到一定條件即可購買,也有一些是企業(yè)客戶名單制購買。業(yè)務(wù)選擇非常重要,因為后面所有的步驟都是基于此業(yè)務(wù)數(shù)據(jù)展開的。首先說明一下,粒度這個概念是數(shù)倉建模極其重要的一個概念,我們后期會單獨講解數(shù)倉中重要的兩個概念:粒度和分區(qū)。
這里先舉個例子:對于用戶(這個主題)來說,一個用戶有一個身份證號,一個戶籍地址,多個手機號,多張銀行卡,那么與用戶粒度相同的粒度屬性有身份證粒度,戶籍地址粒度,比用戶粒度更細的粒度有手機號粒度,銀行卡粒度,存在一對一的關(guān)系就是相同粒度。因為維度建模中要求我們,在同一事實表中,必須具有相同的粒度,同一事實表中不要混用多種不同的粒度,不同的粒度數(shù)據(jù)建立不同的事實表。并且從給定的業(yè)務(wù)過程獲取數(shù)據(jù)時,強烈建議從關(guān)注原子粒度開始設(shè)計,也就是從最細粒度開始,因為原子粒度能夠承受無法預(yù)期的用戶查詢。但是上卷匯總粒度對查詢性能的提升很重要的,所以對于有明確需求的數(shù)據(jù),我們建立針對需求的上卷匯總粒度,對需求不明朗的數(shù)據(jù)我們建立原子粒度。聲明粒度意味著精確定義事實表中的一行數(shù)據(jù)表示什么,應(yīng)該盡可能選擇最小粒度,以此來應(yīng)各種各樣的需求。不做聚合操作。- 訂單事實表中一行數(shù)據(jù)表示的是一個訂單中的一個商品項;
- 支付事實表中一行數(shù)據(jù)表示的是一個支付記錄;
3、確認維度
維度表是作為業(yè)務(wù)分析的入口和描述性標識,維度的主要作用是描述業(yè)務(wù)是事實,主要表示的是“誰,何處,何時”等信息。在一堆的數(shù)據(jù)中怎么確認哪些是維度屬性呢,如果該列是對具體值的描述,是一個文本或常量,某一約束和行標識的參與者,此時該屬性往往是維度屬性,掌握事實表的粒度,就能將所有可能存在的維度區(qū)分開,并且要確保維度表中不能出現(xiàn)重復數(shù)據(jù),應(yīng)使維度主鍵唯一。后續(xù)需求中是否要分析相關(guān)維度的指標。例如,需要統(tǒng)計,什么時間下的訂單多,哪個地區(qū)下的訂單多,哪個用戶下的訂單多。需要確定的維度就包括:時間維度、地區(qū)維度、用戶維度。4、確認事實
此處的“事實”一詞,指的是業(yè)務(wù)中的度量值(次數(shù)、個數(shù)、件數(shù)、金額,可以進行累加),例如訂單金額、下單次數(shù)等。事實表中的每行對應(yīng)一個度量,每行中的數(shù)據(jù)是一個特定級別的細節(jié)數(shù)據(jù),即粒度。維度建模的核心原則之一是同一事實表中的所有度量必須具有相同的粒度。這樣能確保不會出現(xiàn)重復計算度量的問題。判斷原則是:事實表數(shù)值類型和可加類事實。所以可以通過分析該列是否是一種包含多個值并作為計算的參與者的度量,這種情況下該列往往是事實。確認事實一般在數(shù)倉的DWD(Data Warehouse Detail)層,后面會講解數(shù)據(jù)倉庫的分層,以業(yè)務(wù)過程為建模驅(qū)動,基于每個具體業(yè)務(wù)過程的特點,構(gòu)建最細粒度的明細層事實表。事實表可做適當?shù)膶挶砘幚怼?/span>為了應(yīng)對更復雜的業(yè)務(wù)需求,可以將能關(guān)聯(lián)上的表盡量關(guān)聯(lián)上。如何判斷是否能夠關(guān)聯(lián)上呢?在業(yè)務(wù)表關(guān)系圖中,只要兩張表能通過中間表能夠關(guān)聯(lián)上,就說明能關(guān)聯(lián)上。

至此,維度建模4步驟已經(jīng)完成,這四步是必須按照順序執(zhí)行。
其實數(shù)倉建模中還有些其他建模體系:
像DataVault、Anchor模型,這兩個模型感興趣的可以參考浪尖下面的文章。
推薦閱讀
數(shù)倉建模方法論
維度建模技術(shù)實踐——深入事實表
聊聊維度建模的靈魂所在——維度表設(shè)計
漫談數(shù)據(jù)倉庫之維度建模