事實表是維度建模的核心,緊緊圍繞著業務過程來設計,通過描述度量來表達業務過程,包含了維度的引用和業務度量值。
上一篇文章我們講了《維度表的設計》,今天我們聊一下事實表的設計。一樣,我們的目錄結構和內容參考了《阿里巴巴大資料之路》一書。
事實表的基礎
概念
粒度
事實表中的每一條記錄所表達的業務細節程度被稱為粒度。
粒度由兩種方式表述:
- 維度屬性組合所表示的細節程度
- 所表示的具體業務含義
事實
用來描述業務過程的度量,一般是整形、浮點型的十進位制數值。
- 可加:對任何維度進行彙總
- 半可加:只能對特定維度進行彙總,如庫存,按照地點、商品維度彙總是有意義的,按時間彙總是無意義的
- 不可加:比率型,需要拆解為可加的度量來實現彙總,如商品購買率=> 購買人數,瀏覽人數
相對於維度表,事實表會顯得更細長,變化速度也會比維度錶快。
事實表中也是可以儲存維度屬性的,這種操作稱為——維度退化,而相應的維度屬性稱為——退化維度。
事實表型別
- 事務事實表:按最細粒度來儲存業務過程的資料,如購買商品事實表
- 週期快照事實表:按照固定的時間間隔(年、月、日),記錄事實
- 累計快照事實表:覆蓋整個業務生命週期,從開始到結束的累計事實,通常具有多個日期時間欄位來記錄關鍵的時間點,當生命週期發生變化,記錄也會隨之被修改。
設計原則
原則一:儘可能包含所有與業務過程相關的事實
事實表的設計目的是為了度量業務過程。所以分析哪些事實與業務過程有關,是設計中非常重要的關注點。在事實表中應儘量包含所有與該業務過程相關的事實,即使有冗餘,但因為事實通常是數字型,帶來儲存開銷不會很大!
原則二:只選擇與業務過程相關的事實
在選擇事實時,應該注意只選擇與業務過程有關的事實。比如在下單的業務過程中,不應該存在支付金額這一個屬於支付業務過程的事實。
原則三:不可加的事實拆分為可加的度量
如商品購買率 => 購買人數,瀏覽人數
原則四:在選擇維度和事實之前必須先宣告粒度
一般在設計事實表過程中,粒度定義越細越好,從最低階別的原子粒度開始能滿足之後無法預期的使用者需求。
在事實表中,通常通過業務描述來表述粒度(DWD),但對於聚集型的事實表(DWS),可通過單維度或者維度組合的方式來表述。
原則五:在同一個事實表中不能有多種不同粒度的事實
如下表,包含了小訂單粒度、大訂單粒度。大訂單B1包含了小訂單(L1001、L1002、L1003),很明顯如果這兩層不同粒度同時存在一張事實表,當彙總大訂單付款金額時,會造成重複計算的問題。所以,大訂單付款金額應該從此表刪除。
小訂單ID
|
大訂單ID
|
小訂單付款金額
|
小訂單購買數量
|
大訂單付款金額
|
L1001
|
B1
|
100
|
1
|
400
|
L1002
|
B1
|
100
|
2
|
400
|
L1003
|
B1
|
200
|
1
|
400
|
L1004
|
B2
|
123
|
4
|
123
|
L1005
|
B3
|
143
|
1
|
143
|
L1006
|
B4
|
53
|
3
|
53
|
原則六:事實的單位要保持一致
如金額統一成元或者分。
原則七:對事實的null值要處理
null值在特定的SQL查詢引擎中是無法做彙總、比較或者過濾處理的,所以需要統一用零值填充。
原則八:使用退化維度提高事實表的可用性
維度退化到事實表最能提高使用表的效率,應儘量把常用、多用的維度屬性退化到事實表中。比如,在事實表中增加商品維度表(商品名稱),在查詢商品名稱彙總資訊時就不需要再關聯商品維表,減少I/O。
設計方法
- 確定業務需求和事實表的型別
進行詳細的需求分析,分析業務整個生命週期,明確關鍵業務步驟,篩選與需求相關的業務過程。
- 宣告粒度
儘量選擇原子粒度
- 確定維度
粒度宣告後,也意味著確定了主鍵,對應的維度組合跟相關維度欄位也可以確定了
- 確定事實
確定“這個過程的度量有什麼”,拆分不可加事實
- 冗餘維度
維度儘可能退化到事實表中
事務事實表
設計過程
任何型別的時間都可以理解為一種事務。
針對這些食物構建事實表,用以跟蹤自定義業務過程的個體行為,提供豐富的分析能力,作為資料倉儲原子的明細資料。
下面以淘寶交易事務事實表為例,闡述事務事實表的設計過程。
選擇業務過程
訂單的流轉過程:建立訂單 》 買家付款 》 賣家發貨 》 買家確認收貨
對應 下單,支付,發貨,成功 四個業務過程,這四個業務過程是交易中最重要的時間節點。
確定資料粒度
目前在淘寶下單交易時,有兩種方式購買,
一是選定商品直接購買,這樣會產生一個訂單;
二是選擇多種商品加入購物車後,再一起結算,這樣每一種商品都會產生一個小訂單,同時針對同一個店鋪會額外產生一個大訂單(由於是同一個店鋪購買,所以大訂單會承載了物流資訊、店鋪優惠資訊等)。
我們選擇子訂單為資料粒度。
確定維度
維度包含:買家、賣家、商品、商品類目、發貨地區、收貨地區、大訂單維度以及雜項維度。
所以我們可以簡單把事實表理解為一下結構:
事實表 = 主鍵 + 度量 + 相關維度ID和退化維度
確定事實
以淘寶交易事務事實表為例,選定三個業務過程:下單、支付和成功完結,不同的業務過程有不同的事實。
下單:下單金額、下單數量、下單分攤金額,下單優惠金額支付:支付金額、分攤郵費、折扣金額、紅包金額、積分金額成功完結:確認收貨金額
由於是小訂單維度,所以大訂單產生的金額需要分攤回子訂單上,如:郵費、店鋪折扣等。具體會在父子事實的處理方式中詳述。
冗餘維度
將買賣家星級、標籤、店鋪名稱、商品型別、商品特徵、商品屬性、類目層級等維度屬性都冗餘到事實表中,提高對事實表進行過濾查詢、統計聚合的效率。
單事務事實表
上面圖11.5中遺留一個問題:對於事實表中能否包含多個業務過程(下單、支付),還沒有給出定論。
如果我們將業務過程分開處理那就是單事務事實表,參考以下形式:
我們會發現其實下單和支付業務的維度是一樣的,只有度量不一樣。
那我們是否能把兩個業務過程合併起來?答案是可以的。
多事務事實表
講不同的事實合併到同一個事實表中(一個事實表包含多個業務過程)。
合併後,針對度量我們有兩種處理方式
- 不同的事實按照不同的欄位存放
- 新增一個Flag標識業務過程,事實存放到同一個欄位
確定業務過程和資料粒度
下單、支付、成功完結都有相同的資料粒度,都是子訂單粒度,合適放到同一個事實表中。
確定維度
依然還是買家、賣家、商品、商品類目、發貨地區、收貨地區等
確定事實
多事務事實表最重要的是,如何處理多個事實。上面也說了兩種方法。
採用方法一,用多個度量去儲存且一個業務過程雜項維度標記,如:是否當天下單、是否當天支付、是否當天成功完結,標籤之間互不相干。
採用方法二,統一一個度量儲存,且一個業務過程增加一個標籤標記。
如收藏商品事務事實表,增加一個標記【收藏事件型別 1=收藏,2=刪除】來區分。不過收藏事務事實表,無事實,一般用於統計收藏或者刪除的次數。
什麼時候使用多事務事實表
- 當不同業務過程的度量比較相似、差異不大時,可以採用第二種多事務事實表的設計方式,使用同 個欄位來表示 資料。但這種方式存在 個問題一一在同一個週期內會存在多條記錄。
- 當不同業務過程的度量差異較大時,可以選擇第一種事務事實表的設計方式,將不同業務過程的度量使用不同欄位冗餘到表中,非當前業務過程則置零表示。這種方式所存在的問題是度量欄位零值較多。
兩種事實表對比
事實的設計準則
- 事實完整性:事實表包含與其描述的過程有關的所有事實。如淘寶交易事務事實表中的支付業務,包含支付金額、支付郵費、支付紅包、支付積分、支付折扣
- 事實一致性:統一、預先、儘可能地算好一些公式類的指標
- 事實可加性
週期快照事實表
特性
用快照取樣狀態
以預訂的時間間隔取樣狀態度量(如:自然年初截止當日的下單金額),聯合一個或者多個維度定義事實表的粒度。
快照粒度
週期+某個維度(如:商家的每月彙總事實、商家累計交易事實)
密度與稀疏性
週期快照事實表與事務型事實表關鍵區別在於:密度。事務事實表是稀疏的(有發生才會記錄),而週期快照事實表是稠密的(無論發生與否都記錄)。
半可加性
週期快照事實表中收集到的狀態度量都是半可加的。(如:商家累計的下單金額)
產出方式
- 從事務型事實表彙總產出
- 從ODS(或操作性系統資料)產出
例項
設計週期快照事實表有兩個步驟
- 確定快照粒度
- 確定取樣的狀態度量
單維度的日快照事實表
1. 確定粒度
取樣週期為每日,針對賣家、買家、商品、類目、地區等維度構建週期快照事實表。如賣家歷史至今彙總事實表,商品自然月至今彙總事實表。
2. 確定狀態度量
【賣家歷史至今彙總事實表】(業務日期,賣家ID,歷史截止至當日的下單金額,歷史截止至當日的下單買家數)
同樣,商品日快照事實表
多維度的日快照事實表
多維度快照事實表其實是在單維度快照事實表中增加維度,如買賣家歷史至今快照事實表。
注意事項
1. 事務與週期快照一般是成對出現的。
2. 附加事實:
- 有可能會在週期事實表中增加上一個週期的狀態度量
- 一般會有:歷史至當日、自然年至當日、季度至當日、財年至當日等配套出現
累積事實表
累積事實表,一般用於滿足求事件之間的時長這種需求的。
設計過程
建模過程與事務事實表相同,適用於維度建模的步驟。
特點
- 資料會不斷更新
- 有多個關鍵業務過程的日期(代表了生命週期)
特殊處理
如果出現關鍵業務過程非線性的情況(如下單後就關閉訂單,而非走正常的下單-支付-發貨-確認發貨),那就從業務需求角度,確定好關鍵過程後再做累積事實表的設計。
物理實現
- 走全量表,一天一個全量分割槽,但是資料量大的情況會儲存很多永遠不會再更新的歷史資料,不理想
- 走全量表的變化形式,歸定每天儲存前N天內的資料,超過的那部分歸檔處理,也不怎麼理想
- 規定生命週期代表結束的業務過程,如訂單結束/訂單關閉,每天的分割槽存放當天結束的資料,然後設計一個無限大的分割槽(如:9999-12-31),來儲存截止當天尚未走向生命週期結束的資料。理想,但是這種實現方式難點是如何確定訂單結束。
三種事實表比較
無事實的事實表
一般有兩種
- 事件類:如收藏購物車、瀏覽頁面、點選等,其事實為1,但一般不儲存
- 條件、範圍、資格類:記錄維度之間多對多的關係,如:客戶和銷售人員的分配情況,產品的促銷範圍等
聚集型事實表
聚集型(彙總型)事實表的出現,其實就是為了解決資料倉儲效能問題。其實絕大部分資料都可以直接通過加工明細資料得出,但是我們會發現,每個企業都會有自己固定的、必須會看的資料,這部分資料如果經常看,數倉開發要經常查,資料分析也經常做重複的事情,那就有必要把這些資料根據固定維度固化到聚集型事實表中。一般來說,聚集只針對明細層而言,所以聚集不跨域、不跨越事實(意思是得按照明細層的原子指標,按照業務需求加工出多個衍生指標)。
聚集的原則
- 一致性:必須保證聚集後的資料與明細資料有一致的查詢結果
- 避免單一表設計:一個表內的行不能存不同粒度的聚集資料。如有些行存放天彙總資料、有些行存放月彙總資料。應把天、月彙總資料分兩列存放,列明必須標註好註釋。
- 聚集粒度可以不同:聚集不需保持與明細粒度資料一樣的粒度
聚集的步驟
- 確定維度
- 確定一致性上鑽
- 確定事實
聚集的補充說明
- 聚集不跨越事實:事實都是從明細層過來的(注意別走偏了,聚集不跨越事實,但可包含同一個事實的不同度量)
- 聚集的問題:聚集是把常用的,固定粒度的資料沉澱下來。萬一資料粒度改變,表需要重新做