事實表是次元模組化的核心,緊緊圍繞着業務過程來設計,通過描述度量來表達業務過程,包含了次元的引用和業務路徑成本。
上一篇文章我們講了《次元表的設計》,今天我們聊一下事實表的設計。一樣,我們的目錄結構和内容參考了《阿裡巴巴大資料之路》一書。
事實表的基礎
概念
粒度
事實表中的每一條記錄所表達的業務細節程度被稱為粒度。
粒度由兩種方式表述:
- 次元屬性組合所表示的細節程度
- 所表示的具體業務含義
事實
用來描述業務過程的度量,一般是整形、浮點型的十進制數值。
- 可加:對任何次元進行彙總
- 半可加:隻能對特定次元進行彙總,如庫存,按照地點、商品次元彙總是有意義的,按時間彙總是無意義的
- 不可加:比率型,需要拆解為可加的度量來實作彙總,如商品購買率=> 購買人數,浏覽人數
相對于次元表,事實表會顯得更細長,變化速度也會比次元表快。
事實表中也是可以存儲次元屬性的,這種操作稱為——次元退化,而相應的次元屬性稱為——退化次元。
事實表類型
- 事務事實表:按最細粒度來儲存業務過程的資料,如購買商品事實表
- 周期快照事實表:按照固定的時間間隔(年、月、日),記錄事實
- 累計快照事實表:覆寫整個業務生命周期,從開始到結束的累計事實,通常具有多個日期時間字段來記錄關鍵的時間點,當生命周期發生變化,記錄也會随之被修改。
設計原則
原則一:盡可能包含所有與業務過程相關的事實
事實表的設計目的是為了度量業務過程。是以分析哪些事實與業務過程有關,是設計中非常重要的關注點。在事實表中應盡量包含所有與該業務過程相關的事實,即使有備援,但因為事實通常是數字型,帶來存儲開銷不會很大!
原則二:隻選擇與業務過程相關的事實
在選擇事實時,應該注意隻選擇與業務過程有關的事實。比如在下單的業務過程中,不應該存在支付金額這一個屬于支付業務過程的事實。
原則三:不可加的事實拆分為可加的度量
如商品購買率 => 購買人數,浏覽人數
原則四:在選擇次元和事實之前必須先聲明粒度
一般在設計事實表過程中,粒度定義越細越好,從最低級别的原子粒度開始能滿足之後無法預期的使用者需求。
在事實表中,通常通過業務描述來表述粒度(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),來儲存截止當天尚未走向生命周期結束的資料。理想,但是這種實作方式難點是如何确定訂單結束。
三種事實表比較
【資料倉庫】|4 次元模組化之事實表設計
無事實的事實表
一般有兩種
- 事件類:如收藏購物車、浏覽頁面、點選等,其事實為1,但一般不儲存
- 條件、範圍、資格類:記錄次元之間多對多的關系,如:客戶和銷售人員的配置設定情況,産品的促銷範圍等
聚集型事實表
聚集型(彙總型)事實表的出現,其實就是為了解決資料倉庫性能問題。其實絕大部分資料都可以直接通過加工明細資料得出,但是我們會發現,每個企業都會有自己固定的、必須會看的資料,這部分資料如果經常看,數倉開發要經常查,資料分析也經常做重複的事情,那就有必要把這些資料根據固定次元固化到聚集型事實表中。一般來說,聚集隻針對明細層而言,是以聚集不跨域、不跨越事實(意思是得按照明細層的原子名額,按照業務需求加工出多個衍生名額)。
聚集的原則
- 一緻性:必須保證聚集後的資料與明細資料有一緻的查詢結果
- 避免單一表設計:一個表内的行不能存不同粒度的聚集資料。如有些行存放天彙總資料、有些行存放月彙總資料。應把天、月彙總資料分兩列存放,列明必須标注好注釋。
- 聚集粒度可以不同:聚集不需保持與明細粒度資料一樣的粒度
聚集的步驟
- 确定次元
- 确定一緻性上鑽
- 确定事實
聚集的補充說明
- 聚集不跨越事實:事實都是從明細層過來的(注意别走偏了,聚集不跨越事實,但可包含同一個事實的不同度量)
- 聚集的問題:聚集是把常用的,固定粒度的資料沉澱下來。萬一資料粒度改變,表需要重新做