1. 程式人生 > >數倉建設中最常用模型--Kimball維度建模詳解

數倉建設中最常用模型--Kimball維度建模詳解

> 數倉建模首推書籍《資料倉庫工具箱:維度建模權威指南》,**本篇文章參考此書而作**。 文章首發公眾號:五分鐘學大資料,公眾號中傳送“維度建模”即可獲取此書籍第三版電子書 先來介紹下此書,此書是基於作者 60 多年的實際業務環境而總結的經驗及教訓,為讀者提供正式的維度設計和開發技術。面向數倉和BI設計人員,書中涉及到的內容非常廣泛,圍繞一系列的商業場景或案例研究進行組織。強烈建議買一本實體書研究,反覆通讀全書至少三遍以上,你的技術將會有質的飛躍。 ![數倉工具箱](https://cdn.jsdelivr.net/gh/sunmyuan/cdn/210111.png) 因為本文是純理論知識,密密麻麻的字,很多人可能看不下去,所以我儘量用最少的字來表達,儘量將晦澀難懂的詞語轉化為通俗易於理解的詞,將文中的重點加粗展示,內容儘量精簡,以保證在不表達錯誤的情況下更利於讀者學習!希望和大家能一起學習,一起進步,努力到達我們自己的金字塔頂部 ### 維度建模是什麼 維度模型是資料倉庫領域大師Ralph Kimball 所倡導,**以分析決策的需求出發構建模型,構建的資料模型為分析需求服務,因此它重點解決使用者如何更快速完成分析需求,同時還有較好的大規模複雜查詢的響應效能**。 維度建模是 資料倉庫/商業智慧 專案成功的關鍵,為什麼這麼說,因為不管我們的資料量從GB到TG還是到PB,雖然資料量越來越大,但是資料展現要獲得成功,就必須建立在簡單性的基礎之上,**而維度建模就是時刻考慮如何能夠提供簡單性,以業務為驅動,以使用者理解性和查詢效能為目標**。 維度建模:維度建模是專門應用於分析型資料庫、資料倉庫、資料市集建模的方法。資料市集可以理解為一種“小型的資料倉庫” 維度建模指導我們在資料倉庫中如何建表 維度建模分為兩種表:事實表和維度表 1. **事實表**:必然存在的一些資料,像採集的日誌檔案,訂單表,都可以作為事實表 特徵:是一堆主鍵的集合,每個主鍵對應維度表中的一條記錄,客觀存在的,根據主題確定出需要使用的資料 2. **維度表**:維度就是所分析的資料的一個量,維度表就是以合適的角度來建立的表,分析問題的一個角度:時間、地域、終端、使用者等角度 維度建模的三種模式 1. **星形模式**:以事實表為中心,所有的維度表直接連在事實表上,最簡單最常用的一種 ![星形模式](https://cdn.jsdelivr.net/gh/sunmyuan/cdn/xingxing.png) 2. **雪花模式**:雪花模式的維度表可以擁有其他的維度表,這種表不易維護,一般不推薦使用 ![雪花模式](https://cdn.jsdelivr.net/gh/sunmyuan/cdn/xuehua.png) 3. **星座模型**:基於多張事實表,而且共享維度資訊,即事實表之間可以共享某些維度表 ![星座模型](https://cdn.jsdelivr.net/gh/sunmyuan/cdn/xingzuo.png) ### 維度建模怎麼建 我們知道事實表,維度表,星形模型,星座模型這些概念了,但是實際業務中,給了我們一堆資料,我們怎麼拿這些資料進行數倉建設呢,數倉工具箱作者根據自身60多年的實際業務經驗,給我們總結了如下四步,請務必記住! 數倉工具箱中的維度建模四步走: ![維度建模四步走](https://cdn.jsdelivr.net/gh/sunmyuan/cdn/201231_1.png) 請**牢記**以上四步,不管什麼業務,就按照這個步驟來,順序不要搞亂,因為這四步是環環相扣,步步相連。下面詳細拆解下每個步驟怎麼做 **1、選擇業務過程** 維度建模是緊貼業務的,所以必須以業務為根基進行建模,那麼選擇業務過程,顧名思義就是在整個業務流程中選取我們需要建模的業務,根據運營提供的需求及日後的易擴充套件性等進行選擇業務。比如商城,整個商城流程分為商家端,使用者端,平臺端,運營需求是總訂單量,訂單人數,及使用者的購買情況等,我們選擇業務過程就選擇使用者端的資料,商家及平臺端暫不考慮。業務選擇非常重要,因為後面所有的步驟都是基於此業務資料展開的。 **2、宣告粒度** 先舉個例子:對於使用者來說,一個使用者有一個身份證號,一個戶籍地址,多個手機號,多張銀行卡,那麼與使用者粒度相同的粒度屬性有身份證粒度,戶籍地址粒度,比使用者粒度更細的粒度有手機號粒度,銀行卡粒度,存在一對一的關係就是相同粒度。為什麼要提相同粒度呢,因為維度建模中要求我們,在**同一事實表**中,必須具有**相同的粒度**,同一事實表中不要混用多種不同的粒度,不同的粒度資料建立不同的事實表。並且從給定的業務過程獲取資料時,強烈建議從關注原子粒度開始設計,也就是從最細粒度開始,因為原子粒度能夠承受無法預期的使用者查詢。但是上卷彙總粒度對查詢效能的提升很重要的,所以對於有明確需求的資料,我們建立針對需求的上卷彙總粒度,對需求不明朗的資料我們建立原子粒度。 **3、確認維度** 維度表是作為業務分析的入口和描述性標識,所以也被稱為資料倉庫的“靈魂”。在一堆的資料中怎麼確認哪些是維度屬性呢,如果該列是對具體值的描述,是一個文字或常量,某一約束和行標識的參與者,此時該屬性往往是維度屬性,數倉工具箱中告訴我們**牢牢掌握事實表的粒度,就能將所有可能存在的維度區分開**,並且要**確保維度表中不能出現重複資料,應使維度主鍵唯一** **4、確認事實** 事實表是用來度量的,基本上都以數量值表示,事實表中的每行對應一個度量,每行中的資料是一個特定級別的細節資料,稱為粒度。維度建模的核心原則之一**是同一事實表中的所有度量必須具有相同的粒度**。這樣能確保不會出現重複計算度量的問題。有時候往往不能確定該列資料是事實屬性還是維度屬性。記住**最實用的事實就是數值型別和可加類事實**。所以可以通過分析該列是否是一種包含多個值並作為計算的參與者的度量,這種情況下該列往往是事實。 ### 事實表種類 事實表分為以下6類: 1. **事務事實表** 2. **週期快照事實表** 3. **累積快照事實表** 4. **無事實的事實表** 5. **聚集事實表** 6. **合併事實表** 簡單解釋下每種表的概念: - 事務事實表 表中的一行對應空間或時間上某點的度量事件。就是一行資料中必須有度量欄位,什麼是度量,就是指標,比如說銷售金額,銷售數量等這些可加的或者半可加就是度量值。另一點就是事務事實表都包含一個與維度表關聯的外來鍵。並且度量值必須和事務粒度保持一致。 - 週期快照事實表 顧名思義,週期事實表就是每行都帶有時間值欄位,代表週期,通常時間值都是標準週期,如某一天,某周,某月等。粒度是週期,而不是個體的事務,也就是說一個週期快照事實表中資料可以是多個事實,但是它們都屬於某個週期內。 - 累計快照事實表 週期快照事實表是單個週期內資料,而累計快照事實表是由多個週期數據組成,每行彙總了過程開始到結束之間的度量。每行資料相當於管道或工作流,有事件的起點,過程,終點,並且每個關鍵步驟都包含日期欄位。如訂單資料,累計快照事實表的一行就是一個訂單,當訂單產生時插入一行,當訂單發生變化時,這行就被修改。 - 無事實的事實表 我們以上討論的事實表度量都是數字化的,當然實際應用中絕大多數都是數字化的度量,但是也可能會有少量的沒有數字化的值但是還很有價值的欄位,無事實的事實表就是為這種資料準備的,利用這種事實表可以分析發生了什麼。 - 聚集事實表 聚集,就是對原子粒度的資料進行簡單的聚合操作,目的就是為了提高查詢效能。如我們需求是查詢全國所有門店的總銷售額,我們原子粒度的事實表中每行是每個分店每個商品的銷售額,聚集事實表就可以先聚合每個分店的總銷售額,這樣彙總所有門店的銷售額時計算的資料量就會小很多。 - 合併事實表 這種事實表遵循一個原則,就是相同粒度,資料可以來自多個過程,但是隻要它們屬於相同粒度,就可以合併為一個事實表,這類事實表特別適合經常需要共同分析的多過程度量。 ### 維度表技術 1. **維度表結構** 維度表謹記一條原則,包含單一主鍵列,但有時因業務複雜,也可能出現聯合主鍵,請儘量避免,如果無法避免,也要確保必須是單一的,這很重要,如果維表主鍵不是單一,和事實表關聯時會出現資料發散,導致最後結果可能出現錯誤。 維度表通常比較寬,包含大量的低粒度的文字屬性。 2. **跨表鑽取** 跨表鑽取意思是當每個查詢的行頭都包含相同的一致性屬性時,使不同的查詢能夠針對兩個或更多的事實表進行查詢 鑽取可以改變維的層次,變換分析的粒度。它包括上鑽/下鑽: 上鑽(roll-up):上卷是沿著維的層次向上聚集彙總資料。例如,對產品銷售資料,沿著時間維上卷,可以求出所有產品在所有地區每月(或季度或年或全部)的銷售額。 下鑽(drill-down):下鑽是上鑽的逆操作,它是沿著維的層次向下,檢視更詳細的資料。 3. **退化維度** 退化維度就是將維度退回到事實表中。因為有時維度除了主鍵沒有其他內容,雖然也是合法維度鍵,但是一般都會退回到事實表中,減少關聯次數,提高查詢效能 4. **多層次維度** 多數維度包含不止一個自然層次,如日期維度可以從天的層次到周到月到年的層次。所以在有些情況下,在同一維度中存在不同的層次。 5. **維度表空值屬性** 當給定維度行沒有被全部填充時,或者當存在屬性沒有被應用到所有維度行時,將產生空值維度屬性。上述兩種情況,推薦採用描述性字串代替空值,如使用 unknown 或 not applicable 替換空值。 6. **日曆日期維度** 在日期維度表中,主鍵的設定不要使用順序生成的id來表示,可以使用更有意義的資料表示,比如將年月日合併起來表示,即YYYYMMDD,或者更加詳細的