前言
? ? ? ? 今天開始正式數(shù)據(jù)倉庫的內(nèi)容了, 前面我們把生產(chǎn)數(shù)據(jù) , 數(shù)據(jù)上傳到 HDFS , Kafka 的通道都已經(jīng)搭建完畢了, 數(shù)據(jù)也就正式進(jìn)入數(shù)據(jù)倉庫了, 解下來的數(shù)倉建模是重中之重 , 是將來吃飯的家伙?! 以及 Hive SQL 必須熟練到像喝水一樣 !
第1章 數(shù)據(jù)倉庫概述
1.1 數(shù)據(jù)倉庫概念
????????數(shù)據(jù)倉庫 (dataware,簡稱 DW) 是一個為數(shù)據(jù)分析而設(shè)計的企業(yè)級數(shù)據(jù)管理系統(tǒng)。數(shù)據(jù)倉庫可集中、整合多個信息源的大量數(shù)據(jù),借助數(shù)據(jù)倉庫的分析能力,企業(yè)可從數(shù)據(jù)中獲得寶貴的信息進(jìn)而改進(jìn)決策。同時,隨著時間的推移,數(shù)據(jù)倉庫中積累的大量歷史數(shù)據(jù)對于數(shù)據(jù)科學(xué)家和業(yè)務(wù)分析師也是十分寶貴的。
? ? ? ? 數(shù)據(jù)倉庫必須具備存儲 , 管理 , 分析和計算的能力 !
????????數(shù)據(jù)倉庫并不是數(shù)據(jù)的最終目的地 , 而是提供給數(shù)據(jù)倉庫下游的應(yīng)用 !
1.2 數(shù)據(jù)倉庫核心架構(gòu)
????????Hive 一般都是用來作為我們數(shù)據(jù)倉庫的主體 , 因為它具備數(shù)倉必備的存儲 (底層是 HDFS , 所以可以存儲海量數(shù)據(jù)) , 管理 (Hive 可以將我們 HDFS 中的數(shù)據(jù)映射成一張張的二維表)? 以及分析計算 (Hive 支持通過 Hive SQL 來對二維表進(jìn)行分析查詢, 它的引擎可以是 MR / Tez / Spark)
? ? ? ? 業(yè)務(wù)系統(tǒng): 就是企業(yè)當(dāng)中支撐公司核心業(yè)務(wù)的系統(tǒng) , 比如電商公司的核心就是電商業(yè)務(wù)系統(tǒng) , 那么它產(chǎn)生的大量的業(yè)務(wù)數(shù)據(jù)(比如訂單數(shù)據(jù),用戶信息數(shù)據(jù)等)和用戶行為日志數(shù)據(jù)(比如點擊某個按鈕,收藏) 對我們數(shù)據(jù)的分析都是非常有意義的,都需要采集到數(shù)倉當(dāng)中 .
? ? ? ? DataX 是一個基于查詢的全量采集工具 ( select * ) , 而 Maxwell 是基于 binlog 的一個增量數(shù)據(jù)采集工具 .它們都是業(yè)務(wù)數(shù)據(jù)采集工具 (從 MySQL 這種關(guān)系型數(shù)據(jù)庫采集到 HDFS) , 而用戶行為數(shù)據(jù)我們用的一般是 Flume .
? ? ? ? 數(shù)據(jù)采集到數(shù)倉之后就需要把這些 HDFS 文件映射成一張張二維表了 (通過 load 語句),? 之后我們就可以開始進(jìn)行數(shù)倉建模了 . 所謂的數(shù)據(jù)建模就是對數(shù)據(jù)進(jìn)行更加合理高效的存儲整理 , 最終我們的數(shù)據(jù)就被分為多層 , 每層存儲的都是一張張二維表 , 而且每一層都有自己的處理邏輯 , 每一層都是從上一層計算的結(jié)果 .
? ? ? ? 整個數(shù)倉的重點就是 Hive 了 , 我們的主要工作其實就是數(shù)倉的建模和寫 SQL ?. 關(guān)于建模我們要知道每一層的每一張表有哪些字段 , 每一行每一列分別代表什么含義 . SQL 是對數(shù)據(jù)進(jìn)行處理 , 以便發(fā)送給下一層 .
? ? ? ? Hive 數(shù)倉中不同層之間需要執(zhí)行不同的 SQL , 而且必須等待上一層執(zhí)行完才能執(zhí)行 , 這就需要一個調(diào)度框架來協(xié)調(diào)任務(wù)的執(zhí)行了 ( linux 的 crontab 命令并不能滿足這個需求 , 因為 crontab 并不能確定上一個任務(wù)是否執(zhí)行完畢 , 估算可能會出現(xiàn)誤差?) 這里我們用的是 Dolphin Scheduler 這是一個國產(chǎn)的工作流程定時調(diào)度器 (工作流程是由一個個的工作單元組成的 , 就比如我們這里每一層的 SQL )
? ? ? ? 這里強(qiáng)調(diào)最重要的就是數(shù)倉建模和 SQL , 菜就多練 !
第2章 數(shù)據(jù)倉庫建模概述
2.1 數(shù)據(jù)倉庫建模的意義
????????如果把數(shù)據(jù)看作圖書館里的書,我們希望看到它們在書架上分門別類地放置;如果把數(shù)據(jù)看作城市的建筑,我們希望城市規(guī)劃布局合理;如果把數(shù)據(jù)看作電腦文件和文件夾,我們希望按照自己的習(xí)慣有很好的文件夾組織方式,而不是糟糕混亂的桌面,經(jīng)常為找一個文件而不知所措。
????????數(shù)據(jù)模型就是數(shù)據(jù)組織和存儲方法,它強(qiáng)調(diào)從業(yè)務(wù)、數(shù)據(jù)存取和使用角度合理存儲數(shù)據(jù)。只有將數(shù)據(jù)有序的組織和存儲起來之后,數(shù)據(jù)才能得到高性能、低成本、高效率、高質(zhì)量的使用。
- 高性能:良好的數(shù)據(jù)模型能夠幫助我們快速查詢所需要的數(shù)據(jù)。(比如說使用寬表來減少作業(yè)中多表 join 的計算開銷)
- 低成本:良好的數(shù)據(jù)模型能減少重復(fù)計算,實現(xiàn)計算結(jié)果的復(fù)用,降低計算成本。
- 高效率:良好的數(shù)據(jù)模型能極大的改善用戶(數(shù)倉的用戶: 比如下游的應(yīng)用)使用數(shù)據(jù)的體驗,提高使用數(shù)據(jù)的效率。
- 高質(zhì)量:良好的數(shù)據(jù)模型能改善數(shù)據(jù)統(tǒng)計口徑 (防止歧義) 的混亂,減少計算錯誤的可能性。
2.2 數(shù)據(jù)倉庫建模方法論
目前數(shù)倉用的更多的是下面的維度模型,至于 ER 模型更多的是在關(guān)系型數(shù)據(jù)庫中用的比較多 。
2.2.1 ER模型 (了解)
????????數(shù)倉庫之父Bill?Inmon ( 比爾沂蒙?)提出的建模方法是從全企業(yè)的高度,用實體關(guān)系(Entity?Relationship,ER)模型來描述企業(yè)業(yè)務(wù),并用規(guī)范化 ( 數(shù)據(jù)庫規(guī)范化 , 范式等級一般為第三范式 ) 的方式表示出來,在范式理論上符合3NF。? ? ? ?
? ? ? ? 比如說學(xué)生管理系統(tǒng) , 對于學(xué)生和班級這兩個實體的關(guān)系,一個學(xué)生一般對應(yīng)一個班級,但是一個班級對應(yīng)多個學(xué)生,所以我們就可以在學(xué)生表中使用外鍵來關(guān)聯(lián)班級信息.
? ? ? ? 同樣 , 比如學(xué)生表和課程表 , 一個學(xué)生可能有多門課程 , 一們課程也有多個學(xué)生 , 這種關(guān)系用外鍵是實現(xiàn)不了的 , 我們可以在兩張表中間加入一張選課表 , 表中主要就倆字段 學(xué)生id和課程id 就足以說明了兩者之間的關(guān)系了 。
1)實體關(guān)系模型
????????實體關(guān)系模型將復(fù)雜的數(shù)據(jù)抽象為兩個概念——實體和關(guān)系。實體表示一個對象,例如學(xué)生、班級,關(guān)系是指兩個實體之間的關(guān)系,例如學(xué)生和班級之間的從屬關(guān)系。
2)數(shù)據(jù)庫規(guī)范化
????????數(shù)據(jù)庫規(guī)范化是使用一系列范式 (normal form) 設(shè)計數(shù)據(jù)庫(通常是關(guān)系型數(shù)據(jù)庫)的過程,其目的是減少數(shù)據(jù)冗余 (數(shù)據(jù)重復(fù) , 比如有多張表都存儲了同一個字段,比如一張表的一個字段值有重復(fù)?; 因為數(shù)據(jù)冗余會浪費(fèi)存儲空間) ,增強(qiáng)數(shù)據(jù)的一致性 (正因為存在數(shù)據(jù)冗余 , 同一個字段被多次存儲在多張表中 , 如果一張表進(jìn)行了修改但是別的表沒有修改 , 這就造成了數(shù)據(jù)的不一致性問題)。
????????這一系列范式就是指在設(shè)計關(guān)系型數(shù)據(jù)庫時,需要遵從的不同的規(guī)范。關(guān)系型數(shù)據(jù)庫的范式一共有六種,分別是第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF)。遵循的范式級別越高,數(shù)據(jù)冗余性就越低。
3)三范式
????????范式必須按順序去遵守 , 比如遵循了第一范式 , 才能遵循第二范式 , 遵循了第二范式才能遵循第三范式 ... 但是遵循范式并不是越多越好 , 范式級別越高 , 我們的表就被拆分的越細(xì) , 我們的關(guān)系模型就變得復(fù)雜 , 而且我們稍微復(fù)雜一點的查詢可能就需要 join 了 . 一般我們都會做一個折中的取舍 , 選擇第三范式 , 甚至是第二范式 .
(1)函數(shù)依賴
完全函數(shù)依賴:
????????比如 f(x,y) = z ; 我們必須知道三個未知數(shù) x,y,z 中的兩個值才能知道另一個的值 . 對應(yīng)到表中就比如我們必須通過 (學(xué)號,課程名) 才能得到該學(xué)生的分?jǐn)?shù) , 缺一不可 .
部分函數(shù)依賴:
????????比如我們可以通過 (學(xué)號 , 課程名) 來得到學(xué)生的姓名 , 但是要知道學(xué)生的姓名其實并不需要得到課程名 , 這里的 姓名就是部分依賴于? (學(xué)號 , 課程名) 的 .
傳遞函數(shù)依賴:
? ? ? ? 比如 f(x) = y , g(y)?= z , 那么我們就可以通過知道 x 的值來得到 z .對應(yīng)到表中就是我們可以通過學(xué)生的學(xué)號知道這個學(xué)生是哪個系的 , 然后通過系名就可以知道這個系的主任是誰 , 這里就是系主任傳遞函數(shù)依賴于學(xué)號.
(2)第一范式 (1NF)
核心原則: 屬性不可切分 , 對應(yīng)到表中就是字段不可切分
ID | 訂單 | 商家id | 用戶id |
---|---|---|---|
001 | 聯(lián)想小新Pro15 * 5 | xxx旗艦店 | 00001 |
這里上面的屬性 "訂單" 就不符合第一范式 , 因為它可以再拆分為:?
第一范式非常簡單 , 它并沒有函數(shù)依賴 , 但是非常重要 , 因為它是所有范式的基礎(chǔ) .
(3)第二范式 (2NF)
核心原則: 不能存在 "部分函數(shù)依賴" , 對應(yīng)到表中就是 "不能存在非主鍵字段部分函數(shù)依賴于主鍵字段"
????????這里的主鍵是由 "學(xué)號" 和 "課名" 組成的聯(lián)合主鍵 , 可以看到 , 這張表中冗余的部分: 姓名 , 系名和系主任都是部分依賴函數(shù)于聯(lián)合主鍵字段中的學(xué)號的 , 而分?jǐn)?shù)是完全依賴于這個聯(lián)合主鍵的 .
? ? ? ? 消除函數(shù)依賴實現(xiàn)第二范式的方式就是把這張表中完全依賴的部分單獨拆出來:
????????這樣就既滿足了第二范式 , 也解決了數(shù)據(jù)的冗余 . 但是我們還會發(fā)現(xiàn) , 在第二張表中依然存在系名和系主任數(shù)據(jù)冗余的問題 , 這就需要我們來了解一下第三范式了 :
(4)第三范式 (3NF)
核心: 不能存在傳遞函數(shù)依賴 , 對應(yīng)到我們的關(guān)系型數(shù)據(jù)庫表中就是 , 不能存在非主鍵字段傳遞函數(shù)依賴于主鍵字段
?????????這里的學(xué)號可以推出系名 ,? 然后系名可以推出系主任 , 所以這里存在系主任傳遞函數(shù)于學(xué)號( 主鍵 )?, 我們需要繼續(xù)拆表:?
下面我們看一個采用 Bill Inmon 倡導(dǎo)的建模方法(ER 模型) 構(gòu)建的模型 :
????????我們可以看到一張訂單明細(xì)表現(xiàn)在被拆分成了十幾張表 ,?這種建模方法的出發(fā)點是整合數(shù)據(jù),其目的是將整個企業(yè)的數(shù)據(jù)進(jìn)行組合和合并,并進(jìn)行規(guī)范處理,減少數(shù)據(jù)冗余性,保證數(shù)據(jù)的一致性。這種模型并不適合直接用于分析統(tǒng)計。?
? ? ? ? 假如我們要寫一個查詢實現(xiàn)統(tǒng)計出每個國家 2024 年的訂單金額的總額 , 那么我們就需要對上面接近 10 張的表進(jìn)行 join 操作 !
2.2.2 維度模型 (重點)
????????數(shù)據(jù)倉庫領(lǐng)域的另一位大師——Ralph Kimball倡導(dǎo)的建模方法為維度建模。維度模型將復(fù)雜的業(yè)務(wù)通過事實和維度兩個概念進(jìn)行呈現(xiàn)。事實通常對應(yīng)業(yè)務(wù)過程(行為),而維度通常對應(yīng)業(yè)務(wù)過程發(fā)生時所處的環(huán)境(人時地)。
注:業(yè)務(wù)過程可以概括為一個個不可拆分的行為事件,例如電商交易中的下單,取消訂單,付款,退單等,都是業(yè)務(wù)過程。
????????下圖為一個典型的維度模型,其中位于中心的SalesOrder為事實表,其中保存的是下單這個業(yè)務(wù)過程的所有記錄。位于周圍每張表都是維度表,包括Date(日期),Customer(顧客),Product(產(chǎn)品),Location(地區(qū))等,這些維度表就組成了每個訂單發(fā)生時所處的環(huán)境,即何人、何時、在何地下單了何種產(chǎn)品。從圖中可以看出,模型相對清晰、簡潔。
????????維度建模以數(shù)據(jù)分析作為出發(fā)點,為數(shù)據(jù)分析服務(wù),因此它關(guān)注的重點是用戶如何更快的完成需求分析以及如何實現(xiàn)較好的大規(guī)模復(fù)雜查詢的響應(yīng)性能。
? ? ? ? 但是維度模型的缺點也顯而易見,那就是數(shù)據(jù)冗余(主要是維度表),數(shù)據(jù)冗余的問題主要就是存儲浪費(fèi)和數(shù)據(jù)一致性問題,對我們的 Hive 數(shù)倉來說根本不是問題,至于數(shù)據(jù)一致性,由于我們數(shù)倉的數(shù)據(jù)寫進(jìn)來后是不怎么會去修改的,所以數(shù)據(jù)一致性也不是問題。
第3章 維度建模理論之事實表
牢記:所有的事實表它的字段都是由 維度外鍵 和 度量指標(biāo) 組成的!
3.1 事實表概述
????????事實表作為數(shù)據(jù)倉庫維度建模的核心,緊緊圍繞著業(yè)務(wù)過程(下單、退款、付款)來設(shè)計。其包含與該業(yè)務(wù)過程有關(guān)的維度引用(維度表外鍵)以及該業(yè)務(wù)過程的度量(通常是可累加的數(shù)字類型字段,用來量化業(yè)務(wù)過程的字段,比如用下單總金額或者下單的商品數(shù)量來量化下單這個業(yè)務(wù)過程)。
3.1.1 事實表特點
????????事實表通常比較“細(xì)長”,即列較少,但行較多,且行的增速快。
3.1.2 事實表分類
????????事實表有三種類型:分別是事務(wù)事實表、周期快照事實表和累積快照事實表,其中,事務(wù)事實表占據(jù)主要地位,也就是說事務(wù)事實表是常見的,但是周期快照事實表和累積快照事實表是可以不存在的。每種事實表都具有不同的特點和適用場景,下面逐個介紹。
3.2 事務(wù)型事實表(重點)
3.2.1 概述
????????事務(wù)型事實表用來記錄各業(yè)務(wù)過程,它保存的是各業(yè)務(wù)過程的原子操作事件,即最細(xì)粒度的操作事件。粒度是指事實表中一行數(shù)據(jù)所表達(dá)的業(yè)務(wù)細(xì)節(jié)程度。比如訂單信息表和訂單明細(xì)表,訂單信息表中每一行存儲的是每個訂單(包含多個商品)的數(shù)據(jù),而訂單明細(xì)表中每一行存儲的是每個訂單中的每個商品的信息。
????????事務(wù)型事實表可用于分析與各業(yè)務(wù)過程相關(guān)的各項統(tǒng)計指標(biāo),由于其保存了最細(xì)粒度的記錄,可以提供最大限度的靈活性,可以支持無法預(yù)期的各種細(xì)節(jié)層次的統(tǒng)計需求。
3.2.2 設(shè)計流程
????????設(shè)計事務(wù)事實表時一般可遵循以下四個步驟:選擇業(yè)務(wù)過程→聲明粒度→確認(rèn)維度→確認(rèn)事實
1)選擇業(yè)務(wù)過程
????????在業(yè)務(wù)系統(tǒng)中,挑選我們感興趣的業(yè)務(wù)過程(也就是我們的需求),業(yè)務(wù)過程可以概括為一個個不可拆分的行為事件,例如電商交易中的下單,取消訂單,付款,退單等,都是業(yè)務(wù)過程。通常情況下,一個業(yè)務(wù)過程對應(yīng)一張事務(wù)型事實表。
2)聲明粒度(確定每行代表什么)
????????業(yè)務(wù)過程確定后,需要為每個業(yè)務(wù)過程聲明粒度。即精確定義每張事務(wù)型事實表的每行數(shù)據(jù)表示什么,應(yīng)該盡可能選擇最細(xì)粒度,以此來應(yīng)各種細(xì)節(jié)程度的需求。
典型的粒度聲明如下:
????????訂單事實表中一行數(shù)據(jù)表示的是一個訂單中的一個商品項。
3)確定維度(確定維度外鍵)
????????確定維度具體是指,確定與每張事務(wù)型事實表相關(guān)的維度有哪些。
? ? ? ? 確定維度時應(yīng)盡量多的選擇與業(yè)務(wù)過程相關(guān)的環(huán)境信息。因為維度的豐富程度就決定了維度模型能夠支持的指標(biāo)豐富程度。
4)確定事實(確定度量指標(biāo))
????????此處的“事實”一詞,指的是每個業(yè)務(wù)過程的度量值(通常是可累加的數(shù)字類型的值,例如:次數(shù)、個數(shù)、件數(shù)、金額等)。
????????經(jīng)過上述四個步驟,事務(wù)型事實表就基本設(shè)計完成了。第一步選擇業(yè)務(wù)過程可以確定有哪些事務(wù)型事實表,第二步可以確定每張事務(wù)型事實表的每行數(shù)據(jù)是什么,第三步可以確定每張事務(wù)型事實表的維度外鍵,第四步可以確定每張事務(wù)型事實表的度量值字段。
3.2.3 不足
????????事務(wù)型事實表可以保存所有業(yè)務(wù)過程的最細(xì)粒度的操作事件,故理論上其可以支撐與各業(yè)務(wù)過程相關(guān)的各種統(tǒng)計粒度的需求。但對于某些特定類型的需求,其邏輯可能會比較復(fù)雜,或者效率會比較低下。例如:
1)存量型指標(biāo)
????????例如商品庫存,賬戶余額等。此處以電商中的虛擬貨幣(淘金幣、京豆)為例,虛擬貨幣業(yè)務(wù)包含的業(yè)務(wù)過程主要包括獲取貨幣和使用貨幣,兩個業(yè)務(wù)過程各自對應(yīng)一張事務(wù)型事實表,一張存儲所有的獲取貨幣的原子操作事件,另一張存儲所有使用貨幣的原子操作事件。
????????假定現(xiàn)有一個需求,要求統(tǒng)計截至當(dāng)日的各用戶虛擬貨幣余額。由于獲取貨幣和使用貨幣均會影響到余額,故需要對兩張事務(wù)型事實表進(jìn)行聚合,且需要區(qū)分兩者對余額的影響(加或減),另外需要對兩張表的全表數(shù)據(jù)聚合才能得到統(tǒng)計結(jié)果。
????????可以看到,不論是從邏輯上還是效率上考慮(事務(wù)事實表非常大,做聚合操作比較耗時),這都不是一個好的方案。
2)多事務(wù)關(guān)聯(lián)統(tǒng)計
????????例如,現(xiàn)需要統(tǒng)計最近30天,用戶下單到支付的時間間隔的平均值。統(tǒng)計思路應(yīng)該是找到下單事務(wù)事實表和支付事務(wù)事實表,以訂單id作為關(guān)聯(lián)條件join得到下單時間和支付時間,過濾出最近30天的記錄,然后按照訂單id對兩張事實表進(jìn)行關(guān)聯(lián),之后用支付時間減去下單時間,然后再求平均值。
????????邏輯上雖然并不復(fù)雜,但是其效率較低,應(yīng)為下單事務(wù)事實表和支付事務(wù)事實表均為大表,大表 join 大表的操作應(yīng)盡量避免。
????????可以看到,在上述兩種場景下事務(wù)型事實表的表現(xiàn)并不理想。下面要介紹的另外兩種類型的事實表就是為了彌補(bǔ)事務(wù)型事實表的不足的。其中,周期型快照事實表就是用來解決存量型指標(biāo)的,而累積型快照事實表就是用來解決多事務(wù)關(guān)聯(lián)統(tǒng)計的。
3.3 周期型快照事實表
3.3.1 概述
????????周期快照事實表以具有規(guī)律性的、可預(yù)見的時間間隔來記錄事實,主要用于分析一些存量型(例如商品庫存,賬戶余額)或者狀態(tài)型(空氣溫度,行駛速度)指標(biāo)。
????????對于商品庫存、賬戶余額這些存量型指標(biāo),業(yè)務(wù)系統(tǒng)中(MySQL)通常就會計算并保存最新結(jié)果,所以定期同步一份全量數(shù)據(jù)到數(shù)據(jù)倉庫,構(gòu)建周期型快照事實表,就能輕松應(yīng)對此類統(tǒng)計需求,而無需再對事務(wù)型事實表中大量的歷史記錄進(jìn)行聚合了。
? ? ? ? 周期快照表通常都是分區(qū)表,根據(jù)日期分區(qū)。
????????核心思想就是直接利用業(yè)務(wù)系統(tǒng)重現(xiàn)有的結(jié)果,而不是費(fèi)時地去對事務(wù)事實表(大表)進(jìn)行聚合。
????????對于空氣溫度、行駛速度這些狀態(tài)型指標(biāo),由于它們的值往往是連續(xù)的,我們無法捕獲其變動的原子事務(wù)操作(原子事務(wù)操作:比如下單買了幾件商品花了多少錢),所以無法使用事務(wù)型事實表統(tǒng)計此類需求。而只能定期對其進(jìn)行采樣,構(gòu)建周期型快照事實表(比如每隔 1 小時記錄一下空氣溫度的變化值)。
3.3.2 設(shè)計流程
1)確定粒度(確定每行是什么,以及部分列代表什么)
????????周期型快照事實表的粒度可由采樣周期和維度描述,故確定采樣周期和維度后即可確定粒度。
????????采樣周期通常選擇每日。
????????維度可根據(jù)統(tǒng)計指標(biāo)決定,例如指標(biāo)為統(tǒng)計每個倉庫中每種商品的庫存,則可確定維度為倉庫和商品。
????????確定完采樣周期和維度后,即可確定該表粒度為每日-倉庫-商品(所以這個周期快照表的一行代表每天每個倉庫每個商品的某個指標(biāo)值,我們也就確定了除了度量指標(biāo)的三個列:日期 + 倉庫id + 商品id )。
2)確認(rèn)事實
????????事實也可根據(jù)統(tǒng)計指標(biāo)決定,例如指標(biāo)為統(tǒng)計每個倉庫中每種商品的庫存,則事實為商品庫存。到這里我們也就確定了最后一個字段(度量指標(biāo)):庫存數(shù)量。
3.3.3 事實類型
????????此處的事實類型是指度量值的類型,而非事實表的類型。事實(度量值)共分為三類,分別是可加事實,半可加事實和不可加事實。
1)可加事實
????????可加事實是指可以按照與事實表相關(guān)的所有維度進(jìn)行累加,例如事務(wù)型事實表中的事實。
2)半可加事實
????????半可加事實是指只能按照與事實表相關(guān)的一部分維度進(jìn)行累加,例如周期型快照事實表中的事實。以上述各倉庫中各商品的庫存每天快照事實表為例,這張表中的庫存事實可以按照倉庫或者商品維度進(jìn)行累加,但是不能按照時間維度進(jìn)行累加,因為將每天的庫存累加起來是沒有任何意義的。
總結(jié):事務(wù)型事實表中的事實都是可加事實,周期型快照事實表中的事實都是半可加事實!
3)不可加事實
????????不可加事實是指完全不具備可加性,例如比率型事實(比如退貨率=退貨數(shù)/下單數(shù),我們假如有一張表有兩個字段:商品id,退貨率;顯然不管根據(jù)商品id這個維度還是退貨率這個度量指標(biāo)都是無法累加的)。不可加事實應(yīng)盡量避免,所以通常需要轉(zhuǎn)化為可加事實,例如比率可轉(zhuǎn)化為分子和分母。
3.4 累積型快照事實表
3.4.1 概述
????????累計快照事實表是基于一個業(yè)務(wù)流程(區(qū)別于業(yè)務(wù)過程,業(yè)務(wù)過程指的是一個業(yè)務(wù)的原子操作,而業(yè)務(wù)流程是由多個有關(guān)聯(lián)的業(yè)務(wù)過程組成的)中的多個關(guān)鍵業(yè)務(wù)過程聯(lián)合處理而構(gòu)建的事實表,如交易流程中的下單、支付、發(fā)貨、確認(rèn)收貨業(yè)務(wù)過程。
????????累積型快照事實表通常具有多個日期字段,每個日期對應(yīng)業(yè)務(wù)流程中的一個關(guān)鍵業(yè)務(wù)過程(里程碑)比如下面的 下單日期? -> 支付日期??-> 發(fā)貨日期 -> 收貨日期。
訂單id |
用戶id |
下單日期 |
支付日期 |
發(fā)貨日期 |
確認(rèn)收貨日 期 |
訂單金額 |
支付金額 |
1001 |
1234 |
2020-06-14 |
2020-06-15 |
2020-06-16 |
2020-06-17 |
1000 |
1000 |
維度外鍵(多個業(yè)務(wù)過程對應(yīng)的維度外鍵):
訂單id |
用戶id |
下單日期 |
支付日期 |
發(fā)貨日期 |
確認(rèn)收貨日 期 |
度量值(多個業(yè)務(wù)過程的度量值):
訂單金額 |
支付金額 |
????????累積型快照事實表主要用于分析業(yè)務(wù)過程(里程碑)之間的時間間隔等需求。例如前文提到的用戶下單到支付的平均時間間隔,使用累積型快照事實表進(jìn)行統(tǒng)計,就能避免兩個事務(wù)事實表的關(guān)聯(lián)操作,從而變得十分簡單高效。
? ? ? ? 這里的累積指的是這張表不是一次創(chuàng)建好的,比如用戶下單,我們就可以從訂單事務(wù)事實表中拿到下單日期和下單金額放到我們這張表中;過了一天用戶支付,我們又可以從支付事務(wù)事實表中拿到支付日期和支付金額到這張表 ... 直到用戶收貨,我們就把這張表補(bǔ)充完整了。從而省去了多表 join 的過程。
3.4.2 設(shè)計流程
????????累積型快照事實表的設(shè)計流程同事務(wù)型事實表類似,也可采用以下四個步驟,下面重點描述與事務(wù)型事實表的不同之處。
選擇業(yè)務(wù)過程→聲明粒度→確認(rèn)維度→確認(rèn)事實。
1)選擇業(yè)務(wù)過程
????????選擇一個業(yè)務(wù)流程中需要關(guān)聯(lián)分析的多個關(guān)鍵業(yè)務(wù)過程,多個業(yè)務(wù)過程對應(yīng)一張累積型快照事實表(對比我們之前事務(wù)型事實表選擇業(yè)務(wù)的過程:選擇感興趣的業(yè)務(wù)過程,一個業(yè)務(wù)過程對應(yīng)一張事務(wù)事實表)。
2)聲明粒度
????????精確定義每行數(shù)據(jù)表示的是什么,盡量選擇最小粒度。
3)確認(rèn)維度
????????選擇與每個業(yè)務(wù)過程相關(guān)的維度,需要注意的是,每各業(yè)務(wù)過程均需要一個日期維度。
4)確認(rèn)事實
????????選擇各業(yè)務(wù)過程的度量值。
第4章 維度建模理論之維度表
4.1 維度表概述
????????維度表是維度建模的基礎(chǔ)和靈魂。前文提到,事實表緊緊圍繞業(yè)務(wù)過程進(jìn)行設(shè)計,而維度表則圍繞業(yè)務(wù)過程所處的環(huán)境(何人何時何地)進(jìn)行設(shè)計。維度表主要包含一個主鍵和各種維度字段,維度字段稱為維度屬性。
4.2 維度表設(shè)計步驟
1)確定維度(表)
????????在設(shè)計事實表時,已經(jīng)確定了與每個事實表相關(guān)的維度,理論上每個相關(guān)維度均需對應(yīng)一張維度表。需要注意到,可能存在多個事實表與同一個維度都相關(guān)的情況(比如下單表和支付表這兩個事務(wù)事實表都存在用戶id這個維度外鍵),這種情況需保證維度的唯一性,即只創(chuàng)建一張維度表。另外,如果某些維度表的維度屬性很少(比如支付方式表沒有必要去單獨創(chuàng)建一個維度表,因為它就一個支付方式字段),則可不創(chuàng)建該維度表,而把該表的維度屬性直接增加到與之相關(guān)的事實表中,這個操作稱為維度退化。
pay_id | 支付方式 |
---|---|
1 | 微信 |
2 | 支付寶 |
3 | 銀聯(lián) |
? ? ? ? 注意:前面我們說事實表只有兩種字段:維度外鍵和度量指標(biāo),這里我們引入了第三種字段:維度退化字段。
2)確定主維表和相關(guān)維表
????????此處的主維表和相關(guān)維表均指業(yè)務(wù)系統(tǒng)中與某維度相關(guān)的表。例如業(yè)務(wù)系統(tǒng)中與商品相關(guān)的表有sku_info,spu_info,base_trademark,base_category3,base_category2,base_category1等,其中sku_info就稱為商品維度的主維表(通常情況下粒度最細(xì)的是主維表),其余表稱為商品維度的相關(guān)維表。維度表的粒度通常與主維表相同。
3)確定維度屬性
????????確定維度屬性即確定維度表字段。維度屬性主要來自于業(yè)務(wù)系統(tǒng)中與該維度對應(yīng)的主維表和相關(guān)維表。維度屬性可直接從主維表或相關(guān)維表中選擇,也可通過進(jìn)一步加工得到。
確定維度屬性時,需要遵循以下要求:
(1)盡可能生成豐富的維度屬性
????????維度屬性是后續(xù)做分析統(tǒng)計時的查詢約束條件、分組字段的基本來源,是數(shù)據(jù)易用性的關(guān)鍵。維度屬性的豐富程度直接影響到數(shù)據(jù)模型能夠支持的指標(biāo)的豐富程度。
(2)盡量不使用編碼,而使用明確的文字說明,一般可以編碼和文字共存。
? ? ? ? 比如支付方式,如果有這樣一張維度表用 1 代表微信、2 代表支付寶、3代表銀聯(lián),而不是使用文字,那么維度表那么多如果很多都包含這樣的編碼,之后用起來還得專門去字典表(一般對于這種編碼系統(tǒng)會專門建字典表dic)里去查。所以我們最好使用文字作為維度屬性或者蚊子和編碼都作為維度屬性。
(3)盡量沉淀出通用的維度屬性
????????有些維度屬性的獲取需要進(jìn)行比較復(fù)雜的邏輯處理,例如需要通過多個字段拼接得到(加工)。為避免后續(xù)每次使用時的重復(fù)處理,可將這些維度屬性沉淀到維度表中。比如活動表中:滿多少金額減多少,滿多少件打幾折這種復(fù)雜的邏輯處理涉及到多個維度字段,我們需要進(jìn)行沉淀。
4.3 維度設(shè)計要點
4.3.1 規(guī)范化與反規(guī)范化
????????規(guī)范化是指使用一系列范式設(shè)計數(shù)據(jù)庫的過程,其目的是減少數(shù)據(jù)冗余,增強(qiáng)數(shù)據(jù)的一致性。通常情況下,規(guī)范化之后,一張表的字段會拆分到多張表。
????????反規(guī)范化是指將多張表的數(shù)據(jù)冗余到一張表,其目的是減少join操作(空間換時間),提高查詢性能。
????????在設(shè)計維度表時,如果對其進(jìn)行規(guī)范化,得到的維度模型稱為雪花模型,如果對其進(jìn)行反規(guī)范化,得到的模型稱為星型模型(星型模型更加適合數(shù)據(jù)分析)。
????????數(shù)據(jù)倉庫系統(tǒng)的主要目的是用于數(shù)據(jù)分析和統(tǒng)計,所以是否方便用戶進(jìn)行統(tǒng)計分析決定了模型的優(yōu)劣。采用雪花模型,用戶在統(tǒng)計分析的過程中需要大量的關(guān)聯(lián)操作,使用復(fù)雜度高,同時查詢性能很差,而采用星型模型,則方便、易用且性能好。所以出于易用性和性能的考慮,維度表一般是很不規(guī)范化的。
4.3.2 維度變化
????????維度屬性通常不是靜態(tài)的,而是會隨時間變化的(比如用戶表的手機(jī)號,比如省份表),數(shù)據(jù)倉庫的一個重要特點就是反映歷史的變化,所以如何保存維度的歷史狀態(tài)是維度設(shè)計的重要工作之一。保存維度數(shù)據(jù)的歷史狀態(tài),通常有以下兩種做法,分別是全量快照表和拉鏈表。
1)全量快照表
????????離線數(shù)據(jù)倉庫的計算周期通常為每天一次,所以可以每天保存一份全量的維度數(shù)據(jù)到一個分區(qū)。這種方式的優(yōu)點和缺點都很明顯。
????????優(yōu)點是簡單而有效,開發(fā)和維護(hù)成本低,且方便理解和使用。
????????缺點是浪費(fèi)存儲空間,尤其是當(dāng)數(shù)據(jù)的變化比例比較低時。
????????比如上面這張用戶表,從 2019-01-01 到 2019-05-11并沒有數(shù)據(jù)變化,但是它還是每天全量的進(jìn)行保存。?
2)拉鏈表(重點)
????????拉鏈表的意義就在于能夠更加高效的保存維度信息的歷史狀態(tài)。
(1)什么是拉鏈表
????????拉鏈表,記錄每條信息的生命周期,一旦一條記錄的生命周期結(jié)束,就直接重新開始一條記錄,并把當(dāng)前日期放入生效開始信息。
? ? ? ? 如果當(dāng)前信息至今有效,就在生效結(jié)束日期中填入一個極大值(如 9999-12-31)
(2)為什么要做拉鏈表
? ? ? ? 拉鏈表適合于:數(shù)據(jù)會發(fā)生變化,但是變化頻率并不高的維度(即:緩慢變化維)。英文拉鏈 zip 也可以翻譯為 壓縮,所以拉鏈表也可以理解為壓縮表。
? ? ? ? 比如:用戶信息的變化就不并不高,所以如果按照每日全量的方式保存效率很低。
(3)如何使用拉鏈表
? ? ? ? 拉鏈表同樣是維度表,所以我們依然是用事實表和它去做關(guān)聯(lián),關(guān)聯(lián)的時候的規(guī)則同樣是哪一天發(fā)生的事實去 join 哪天的維度狀態(tài)?,F(xiàn)在的問題是我們?nèi)绾瓮ㄟ^拉鏈表獲得那一天的全量狀態(tài)。
? ? ? ? 對于最新數(shù)據(jù),我們可以直接查詢滿足狀態(tài)結(jié)束日期為 9999-12-31 的數(shù)據(jù)。對于某天的數(shù)據(jù),比如 2023-12-1 我們只要要求 狀態(tài)開始日期 <= 2023-12-1 <= 狀態(tài)結(jié)束日期?即可。
4.3.3 多值維度
? ? ? ? 多值維度是一種現(xiàn)象,是在我們設(shè)計事實表時可能存在的一種現(xiàn)象。如果事實表中一條記錄在某個維度表中有多條記錄與之對應(yīng),稱為多值維度。例如,下單事實表中的一條記錄為一個訂單(這種事實表在創(chuàng)建時沒有考慮周全),一個訂單可能包含多個商品,所會商品維度表中就可能有多條數(shù)據(jù)與之對應(yīng)。
????????針對這種情況,通常采用以下兩種方案解決。
????????第一種:降低事實表的粒度,例如將訂單事實表的粒度由一個訂單降低為一個訂單中的一個商品項。
????????第二種:在事實表中采用多字段保存多個維度值,每個字段保存一個維度id。這種方案只適用于多值維度個數(shù)固定的情況。如果多維度個數(shù)不固定可以使用 Hive 的復(fù)雜數(shù)據(jù)類型(比如數(shù)組)。
????????建議盡量采用第一種方案解決多值維度問題。
4.3.3 多值屬性
? ? ? ? 多值屬性同樣是一種現(xiàn)象,是在我們設(shè)計維度表時可能存在的一種現(xiàn)象。多值維表中的某個屬性同時有多個值,稱之為“多值屬性”,例如商品維度的平臺屬性(比如品牌、CPU,是否支持快充)和銷售屬性(比如規(guī)格、顏色、尺寸),每個商品均有多個屬性值。
????????針對這種情況,通常有可以采用以下兩種方案。
????????第一種:將多值屬性放到一個字段,該字段內(nèi)容為key1:value1,key2:value2的形式,例如一個手機(jī)商品的平臺屬性值為“品牌:華為,系統(tǒng):鴻蒙,CPU:麒麟990”。
????????第二種:將多值屬性放到多個字段,每個字段對應(yīng)一個屬性。這種方案只適用于多值屬性個數(shù)固定的情況。
4.4?維度模型對同步策略的影響
????????這是我們上一篇同步策略中劃分的對于不同業(yè)務(wù)表對應(yīng)不同的同步策略,現(xiàn)在我們可以看到這樣的現(xiàn)象:
- 對于事務(wù)事實表將來需要用到的表通常采用增量同步
- 對于周期快照事實表將來需要用到的表通常采用全量同步
- 對于累積事實表將來需要用到的表通常采用增量同步
- 對于每日全量快照維度表將來需要用到的表通常采用全量同步
- 對于拉鏈表將來需要用到的表通常采用增量同步
比如對上面的 cart_info(購物車信息) 這個表,我們既做一個事務(wù)事實表,也要做周期快照事實表。上面的 user_info 雖然更像是維度表,但是因為它將來要做為拉鏈表,所以采用增量同步。
第5章 數(shù)據(jù)倉庫設(shè)計
5.1 數(shù)據(jù)倉庫分層規(guī)劃
????????優(yōu)秀可靠的數(shù)倉體系,需要良好的數(shù)據(jù)分層結(jié)構(gòu)。合理的分層,能夠使數(shù)據(jù)體系更加清晰,使復(fù)雜問題得以簡化。以下是該項目的分層規(guī)劃。
????????分層的目的就是為了提高開發(fā)效率,就比如我之前開發(fā)一個桌面軟件,因為比較復(fù)雜加上自己沒有相關(guān)經(jīng)驗,導(dǎo)致開發(fā)過程有大量的代碼冗余,這不要緊,主要是屎山難以維護(hù),我的好多工作需要不斷返工?,對之前設(shè)計不合理的地方不斷修改,但是屎山牽一發(fā)動全身,導(dǎo)致我最后狼狽無比,落荒而逃,只能擇日重構(gòu)整個項目。
- ODS 層:只做數(shù)據(jù)準(zhǔn)備(把數(shù)據(jù)原封不動從 HDFS 映射到 Hive 表中)不做數(shù)據(jù)處理
- DWD 層:存放維度模型中的事實表
- DIM 層:存放維度模型中的維度表
- DWS 層:存放后面計算需要的公用中間計算結(jié)果,減少重復(fù)計算。(DWS 層的數(shù)據(jù)大多來自 DWD 層)
- ADS 層:存放各項統(tǒng)計指標(biāo)的結(jié)果
5.2 數(shù)據(jù)倉庫構(gòu)建流程
- 數(shù)據(jù)調(diào)研:業(yè)務(wù)調(diào)研(調(diào)研的是業(yè)務(wù)系統(tǒng)中的數(shù)據(jù),要熟悉業(yè)務(wù)邏輯)和需求分析(數(shù)倉后續(xù)的應(yīng)用的需求)
- 明確數(shù)據(jù)域:對數(shù)據(jù)進(jìn)行分類,為的是從業(yè)務(wù)系統(tǒng)中快速的找到我們希望得到的數(shù)據(jù)
- 構(gòu)建業(yè)務(wù)總線矩陣:其實就是一個二維表格,行代表業(yè)務(wù)過程,列代表維度,如果業(yè)務(wù)過程和某個維度有關(guān)聯(lián)就打?qū)︺^,最終總線矩陣構(gòu)建好之后,其實我們的維度模型也基本構(gòu)建完成了
- 維度模型設(shè)計:構(gòu)建 DWD 層和 DIM 層。維度模型設(shè)計由業(yè)務(wù)驅(qū)動是因為我們的事實表取決于業(yè)務(wù)系統(tǒng)中業(yè)務(wù)過程,我們的維度表取決于業(yè)務(wù)系統(tǒng)中的環(huán)境,它們和我們后面的指標(biāo)并沒有太大關(guān)系。
- 明確統(tǒng)計指標(biāo):要做匯總模型就必須明確統(tǒng)計指標(biāo),為的是找到統(tǒng)計指標(biāo)需要的中間計算結(jié)果。這個過程會對報表需求進(jìn)行分析,整理出指標(biāo)體系,我們可以根據(jù)指標(biāo)體系找到需要存儲在 DWS 層的中間計算結(jié)果。
- 匯總模型設(shè)計:完全依賴于統(tǒng)計指標(biāo)需求,因為只要知道了需求才能知道要存儲哪部分中間結(jié)果,所以匯總模型設(shè)計是需求驅(qū)動的。
5.2.1 數(shù)據(jù)調(diào)研
????????數(shù)據(jù)調(diào)研重點要做兩項工作,分別是業(yè)務(wù)調(diào)研和需求分析。這兩項工作做的是否充分,直接影響著數(shù)據(jù)倉庫的質(zhì)量。
1)業(yè)務(wù)調(diào)研
????????業(yè)務(wù)調(diào)研的主要目標(biāo)是熟悉業(yè)務(wù)流程、熟悉業(yè)務(wù)數(shù)據(jù)。
????????熟悉業(yè)務(wù)流程要求做到,明確每個業(yè)務(wù)的具體流程,需要將該業(yè)務(wù)所包含的每個業(yè)務(wù)過程一一列舉出來。
????????熟悉業(yè)務(wù)數(shù)據(jù)要求做到,將數(shù)據(jù)(包括埋點日志和業(yè)務(wù)數(shù)據(jù)表)與業(yè)務(wù)過程對應(yīng)起來,明確每個業(yè)務(wù)過程會對哪些表的數(shù)據(jù)產(chǎn)生影響,以及產(chǎn)生什么影響。產(chǎn)生的影響,需要具體到,是新增一條數(shù)據(jù),還是修改一條數(shù)據(jù),并且需要明確新增的內(nèi)容或者是修改的邏輯。
????????下面業(yè)務(wù)電商中的交易為例進(jìn)行演示,交易業(yè)務(wù)涉及到的業(yè)務(wù)過程有買家下單、買家支付、賣家發(fā)貨,買家收貨,具體流程如下圖。
????????比如我們要建一張加購表(事務(wù)事實表),那么我們就需要知道這個業(yè)務(wù)過程(加購操作)會對哪些表產(chǎn)生影響。首先我們要從業(yè)務(wù)數(shù)據(jù)中獲取加購操作的信息加載到事實表,就需要有?cart_info 的 binlog 變更日志,Maxwell 的輸出是 json 格式的,對于加購表來說,我們需要知道 type=insert 的數(shù)據(jù)一定是加購操作,至于 type=update 的語句我們需要判斷它修改的是哪個字段,如果修改的是 sku_num (商品數(shù)量)并且數(shù)值是變大的,那這也是加購操作。
2)需求分析
????????典型的需求指標(biāo)如,最近一天各省份手機(jī)品類訂單總額。
????????分析需求時,需要明確需求所需的業(yè)務(wù)過程及維度,例如該需求所需的業(yè)務(wù)過程就是下單這個行為,所需的維度有日期,省份,商品品類。
3)總結(jié)
????????做完業(yè)務(wù)分析和需求分析之后,要保證每個需求都能找到與之對應(yīng)的業(yè)務(wù)過程及維度。若現(xiàn)有數(shù)據(jù)無法滿足需求,則需要和業(yè)務(wù)方進(jìn)行溝通,例如某個頁面需要新增某個行為的埋點。
5.2.2 明確數(shù)據(jù)域
????????數(shù)據(jù)倉庫模型設(shè)計除橫向的分層外,通常也需要根據(jù)業(yè)務(wù)情況進(jìn)行縱向劃分?jǐn)?shù)據(jù)域。劃分?jǐn)?shù)據(jù)域的意義是便于數(shù)據(jù)的管理和應(yīng)用。
????????通??梢愿鶕?jù)業(yè)務(wù)過程或者部門進(jìn)行劃分,本項目根據(jù)業(yè)務(wù)過程進(jìn)行劃分,需要注意的是一個業(yè)務(wù)過程只能屬于一個數(shù)據(jù)域。因為劃分?jǐn)?shù)據(jù)域按照業(yè)務(wù)過程分,所以也就相當(dāng)于在 DWD 層準(zhǔn)備事實表,以及 DWD 上層的 DWS 層的匯總表也會進(jìn)行劃分?jǐn)?shù)據(jù)域,它和 DWD 層是一一對應(yīng)的。但是 DIM 層就不需要劃分?jǐn)?shù)據(jù)域,因為一張維度表可能被多個事實表關(guān)聯(lián),所以無法確定它是哪個數(shù)據(jù)域。
? ? ? ? 所以,只有在 DWD 層和 DWS 層會進(jìn)行數(shù)據(jù)域的劃分,DIM 層不會進(jìn)行數(shù)據(jù)域的劃分。
下面是本數(shù)倉項目所需的所有業(yè)務(wù)過程及數(shù)據(jù)域劃分詳情。
數(shù)據(jù)域 |
業(yè)務(wù)過程 |
交易域 |
加購、下單、取消訂單、支付成功、退單、退款成功 |
流量域 |
頁面瀏覽、啟動應(yīng)用、動作、曝光、錯誤 |
用戶域 |
注冊、登錄 |
互動域 |
收藏、評價 |
工具域 |
優(yōu)惠券領(lǐng)取、優(yōu)惠券使用(下單)、優(yōu)惠券使用(支付) |
????????這里也有一些業(yè)務(wù)過程我們并沒有選擇,比如交易域中還可以有:減購、確認(rèn)收貨等,但是我們在學(xué)習(xí)事務(wù)型事實表的設(shè)計流程中說過,選擇自己感興趣的業(yè)務(wù)流程,也就是我們需求指標(biāo)需要用到的業(yè)務(wù)過程,所以這里沒有選擇。但是如果前瞻性的創(chuàng)建也不是不行。
? ? ? ? 流量域相關(guān)的業(yè)務(wù)過程我們并不能直接從業(yè)務(wù)系統(tǒng)中直接拿到,而是得從用戶行為日志中去獲取。
5.2.3 構(gòu)建業(yè)務(wù)總線矩陣
????????業(yè)務(wù)總線矩陣中包含維度模型所需的所有事實(業(yè)務(wù)過程)以及維度,以及各業(yè)務(wù)過程與各維度的關(guān)系。矩陣的行是一個個業(yè)務(wù)過程,矩陣的列是一個個的維度,行列的交點表示業(yè)務(wù)過程與維度存在關(guān)聯(lián)關(guān)系。
????????一個業(yè)務(wù)過程對應(yīng)維度模型中一張事務(wù)型事實表,一個維度則對應(yīng)維度模型中的一張維度表。所以構(gòu)建業(yè)務(wù)總線矩陣的過程就是設(shè)計維度模型的過程。但是需要注意的是,總線矩陣中通常只包含事務(wù)型事實表,另外兩種類型的事實表(周期快照、累積快照)需要單獨設(shè)計。
????????按照事務(wù)型事實表的設(shè)計流程我們就可以得到業(yè)務(wù)總線矩陣:選擇業(yè)務(wù)過程 ->?聲明粒度 -> 確認(rèn)維度?->?確認(rèn)事實?。
數(shù)據(jù)域 | 業(yè)務(wù)過程 | 粒度 | 維度 | 度量 | ||||||||||
時間 | 用戶 | 商品 | 地區(qū) | 活動(具體規(guī)則) | 優(yōu)惠券 | 支付方式 | 退單類型 | 退單原因類型 | 渠道 | 設(shè)備 | ||||
交易域 | 加購物車 | 一次加購物車的操作 | √ | √ | √ | 商品件數(shù) | ||||||||
下單 | 一個訂單中一個商品項 | √ | √ | √ | √ | √ | √ | 下單件數(shù)/下單原始金額/下單最終金額/活動優(yōu)惠金額/優(yōu)惠券優(yōu)惠金額 | ||||||
取消訂單 | 一次取消訂單操作 | √ | √ | √ | √ | √ | √ | 下單件數(shù)/下單原始金額/下單最終金額/活動優(yōu)惠金額/優(yōu)惠券優(yōu)惠金額 | ||||||
支付成功 | 一個訂單中的一個商品項的支付成功操作 | √ | √ | √ | √ | √ | √ | √ | 支付件數(shù)/支付原始金額/支付最終金額/活動優(yōu)惠金額/優(yōu)惠券優(yōu)惠金額 | |||||
退單 | 一次退單操作 | √ | √ | √ | √ | √ | √ | 退單件數(shù)/退單金額 | ||||||
退款成功 | 一次退款成功操作 | √ | √ | √ | √ | √ | 退款件數(shù)/退款金額 | |||||||
流量域 | 頁面瀏覽 | 一次頁面瀏覽記錄 | √ | √ | √ | √ | √ | 瀏覽時長 | ||||||
動作 | 一次動作記錄 | √ | √ | √ | √ | √ | √ | √ | 無事實(次數(shù)1) | |||||
曝光 | 一次曝光記錄 | √ | √ | √ | √ | √ | √ | √ | 無事實(次數(shù)1) | |||||
啟動應(yīng)用 | 一次啟動記錄 | √ | √ | √ | √ | √ | 無事實(次數(shù)1) | |||||||
錯誤 | 一次錯誤記錄 | √ | √ | √ | √ | 無事實(次數(shù)1) | ||||||||
用戶域 | 注冊 | 一次注冊操作 | √ | √ | 無事實(次數(shù)1) | |||||||||
登錄 | 一次登錄操作 | √ | √ | √ | √ | √ | 無事實(次數(shù)1) | |||||||
工具域 | 領(lǐng)取優(yōu)惠券 | 一次優(yōu)惠券領(lǐng)取操作 | √ | √ | √ | 無事實(次數(shù)1) | ||||||||
使用優(yōu)惠券(下單) | 一次優(yōu)惠券使用(下單)操作 | √ | √ | √ | 無事實(次數(shù)1) | |||||||||
使用優(yōu)惠券(支付) | 一次優(yōu)惠券使用(支付)操作 | √ | √ | √ | 無事實(次數(shù)1) | |||||||||
互動域 | 收藏商品 | 一次收藏商品操作 | √ | √ | √ | 無事實(次數(shù)1) | ||||||||
評價 | 一次取消收藏商品操作 | √ | √ | √ | 無事實(次數(shù)1) |
????????后續(xù)的DWD層以及DIM層的搭建需參考業(yè)務(wù)總線矩陣。
5.2.4 明確統(tǒng)計指標(biāo)
????????明確統(tǒng)計指標(biāo)具體的工作是,深入分析需求(深入了解每個業(yè)務(wù)過程每個指標(biāo)的運(yùn)算邏輯),構(gòu)建指標(biāo)體系。構(gòu)建指標(biāo)體系的主要意義就是指標(biāo)定義標(biāo)準(zhǔn)化。所有指標(biāo)的定義,都必須遵循同一套標(biāo)準(zhǔn),這樣能有效的避免指標(biāo)定義存在歧義,指標(biāo)定義重復(fù)等問題。
1)指標(biāo)體系相關(guān)概念
(1)原子指標(biāo)
????????原子指標(biāo)基于某一業(yè)務(wù)過程的度量值,是業(yè)務(wù)定義中不可再拆解的指標(biāo),原子指標(biāo)的核心功能就是對指標(biāo)的聚合邏輯進(jìn)行了定義。我們可以得出結(jié)論,原子指標(biāo)包含三要素,分別是業(yè)務(wù)過程、度量值和聚合邏輯。
????????例如訂單總額就是一個典型的原子指標(biāo)(它只是完整統(tǒng)計指標(biāo)的一部分),其中的業(yè)務(wù)過程為用戶下單、度量值為訂單金額,聚合邏輯為 sum() 求和。需要注意的是原子指標(biāo)只是用來輔助定義指標(biāo)一個概念,通常不會對應(yīng)有實際統(tǒng)計需求與之對應(yīng)。
(2)派生指標(biāo)
????????派生指標(biāo)基于原子指標(biāo)。
????????與原子指標(biāo)不同,派生指標(biāo)通常會對應(yīng)實際的統(tǒng)計需求。派生指標(biāo)通過公式來使指標(biāo)定義標(biāo)準(zhǔn)化。
? ? ? ? 一般一個派生指標(biāo)都可以通過一張事實表進(jìn)行分組聚合計算得到計算結(jié)果。
(3)衍生指標(biāo)
????????衍生指標(biāo)是在一個或多個派生指標(biāo)的基礎(chǔ)上,通過各種邏輯運(yùn)算復(fù)合而成的。例如比率、比例等類型的指標(biāo)。衍生指標(biāo)也會對應(yīng)實際的統(tǒng)計需求。
? ? ? ? ?所有的衍生指標(biāo)都可以通過一個或多個派生指標(biāo)計算得到。這里的退貨率就需要兩個派生指標(biāo)(下單次數(shù)和退單次數(shù))來進(jìn)行計算得到。
2)指標(biāo)體系對于數(shù)倉建模的意義(主要是對DWS層的意義)
????????通過上述兩個具體的案例可以看出,絕大多數(shù)的統(tǒng)計需求,都可以使用原子指標(biāo)、派生指標(biāo)以及衍生指標(biāo)這套標(biāo)準(zhǔn)去定義。同時能夠發(fā)現(xiàn)這些統(tǒng)計需求都直接的或間接的對應(yīng)一個或者是多個派生指標(biāo)。
????????當(dāng)統(tǒng)計需求足夠多時,必然會出現(xiàn)部分統(tǒng)計需求對應(yīng)的派生指標(biāo)相同的情況。這種情況下,我們就可以考慮將這些公共的派生指標(biāo)保存下來,這樣做的主要目的就是減少重復(fù)計算,提高數(shù)據(jù)的復(fù)用性。
????????這些公共的派生指標(biāo)統(tǒng)一保存在數(shù)據(jù)倉庫的DWS層。因此DWS層設(shè)計,就可以參考我們根據(jù)現(xiàn)有的統(tǒng)計需求整理出的派生指標(biāo):
我們把上面所有的派生指標(biāo)拿出來分析:?
原子指標(biāo) | 統(tǒng)計周期 | 業(yè)務(wù)限定 | 統(tǒng)計粒度 | ||
業(yè)務(wù)過程 | 度量值 | 聚合邏輯 | |||
頁面瀏覽 | * | * | 最近1/7/30日 | 會話 | |
頁面瀏覽 | during_time | sum() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | * | * | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 訪客-頁面 | |
頁面瀏覽 | 1 | count() | 最近1/7/31日 | 訪客-頁面 | |
用戶登錄 | date_id | max() | 歷史至今 | 用戶 | |
用戶登錄 | date_id | max() | 歷史至今 | 用戶 | |
用戶登錄 | date_id | max() | 歷史至今 | 用戶 | |
用戶登錄 | date_id | max() | 歷史至今 | 用戶 | |
加購 | 1 | count() | 最近1/7/30日 | 用戶 | |
下單 | 訂單金額 | sum() | 最近1/7/30日 | 用戶 | |
下單 | order_id | count(distinct()) | 最近1/7/30日 | 用戶 | |
下單 | order_id | count(distinct) | 最近1/7/30日 | 用戶 | |
下單 | order_id | count(distinct) | 最近1/7/30日 | 用戶 | |
下單 | date_id | min() | 歷史至今 | 用戶 | |
下單 | date_id | max() | 歷史至今 | 用戶 | |
下單 | 1 | count() | 最近30日 | 用戶-商品 | |
下單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
下單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
下單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
下單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
下單 | order_id | count(distinct) | 最近1/7/30日 | 省份 | |
下單 | 訂單金額 | sum() | 最近1/7/30日 | 省份 | |
下單 | 訂單原始金額 | sum() | 最近30日 | 訂單使用優(yōu)惠券(coupon_id不為null)且優(yōu)惠券發(fā)布日期在最近30日內(nèi) | 優(yōu)惠券 |
下單 | 優(yōu)惠券優(yōu)惠金額 | sum() | 最近30日 | 訂單使用優(yōu)惠券(coupon_id不為null)且優(yōu)惠券發(fā)布日期在最近30日內(nèi) | 優(yōu)惠券 |
下單 | 訂單原始金額 | sum() | 最近30日 | 訂單參與活動(activity_id不為null)且活動的發(fā)布日期在最近30日內(nèi) | 活動 |
下單 | 活動優(yōu)惠金額 | sum() | 最近30日 | 訂單參與活動(activity_id不為null)且活動的發(fā)布日期在最近30日內(nèi) | 活動 |
退單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
退單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
退單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
退單 | 1 | count() | 最近1/7/30日 | 用戶-商品 | |
退單 | 1 | count() | 最近1/7/30日 | 用戶 | |
退單 | 1 | count() | 最近1/7/30日 | 用戶 | |
支付 | date_id | min() | 歷史至今 | 用戶 | |
支付 | order_id | count(distinct()) | 最近1/7/30日 | 用戶 |
????????這樣我們就可以清楚的看到表中存在很多相同的派生指標(biāo),那我們就可以依據(jù)這些公共的派生指標(biāo)去給 DWS 層建表,但是我們并不是把業(yè)務(wù)過程相同、統(tǒng)計周期相同、統(tǒng)計粒度相同、度量值、聚合邏輯都相同的數(shù)據(jù)放到同一張匯總表,具體設(shè)計看下面的匯總表模型設(shè)計。
5.2.4 維度模型設(shè)計
????????維度模型的設(shè)計參照上述得到的業(yè)務(wù)總線矩陣即可。事實表存儲在DWD層,維度表存儲在DIM層。
5.2.5 匯總模型設(shè)計
????????匯總模型的設(shè)計參考上述整理出的指標(biāo)體系(主要是派生指標(biāo))即可。匯總表與派生指標(biāo)的對應(yīng)關(guān)系是,一張匯總表通常包含業(yè)務(wù)過程相同、統(tǒng)計周期相同、統(tǒng)計粒度相同的多個派生指標(biāo)。而不是非得度量值、聚合邏輯也都相同才放到一張匯總表中(不通需求的度量值和聚合邏輯總是不一樣的)。
? ? ? ? 比如上面的表格中,我們可以發(fā)現(xiàn):
原子指標(biāo) | 統(tǒng)計周期 | 業(yè)務(wù)限定 | 統(tǒng)計粒度 | ||
業(yè)務(wù)過程 | 度量值 | 聚合邏輯 | |||
頁面瀏覽 | * | * | 最近1/7/30日 | 會話 | |
頁面瀏覽 | during_time | sum() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | * | * | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 訪客-頁面 | |
頁面瀏覽 | 1 | count() | 最近1/7/31日 | 訪客-頁面 |
?其中存在完全相同結(jié)構(gòu)的派生指標(biāo):
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 訪客-頁面 |
??? ? ? ?但是我們并不會直接把這種完全相同派生指標(biāo)的計算結(jié)果存儲一份到 DWS 層,而是把具有業(yè)務(wù)過程相同、統(tǒng)計周期相同、統(tǒng)計粒度相同的多個派生指標(biāo)計算結(jié)果分別存到匯總表中:
原子指標(biāo) | 統(tǒng)計周期 | 業(yè)務(wù)限定 | 統(tǒng)計粒度 | ||
業(yè)務(wù)過程 | 度量值 | 聚合邏輯 | |||
頁面瀏覽 | * | * | 最近1/7/30日 | 會話 | |
頁面瀏覽 | during_time | sum() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 | |
頁面瀏覽 | * | * | 最近1/7/30日 | 會話 | |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 會話 |
頁面瀏覽 | 1 | count() | 最近1/7/30日 | 訪客-頁面 | |
頁面瀏覽 | 1 | count() | 最近1/7/31日 | 訪客-頁面 |
????????業(yè)務(wù)過程相同,說明我們會用到同一張事實表;統(tǒng)計周期相同,說明會用到同一張事實表的同一天的數(shù)據(jù);統(tǒng)計粒度相同,說明我們的每一行代表的含義是相同的。
匯總表與事實表的對應(yīng)關(guān)系是?
????????一個匯總表只對應(yīng)一個事實表(因為匯總表必須有相同的業(yè)務(wù)過程,而一個業(yè)務(wù)過程又對應(yīng)一個事實表),但是一個事實表對應(yīng)多個匯總表,因為我們的需求(派生指標(biāo))統(tǒng)計粒度和統(tǒng)計周期可能不同。文章來源:http://www.zghlxwxcb.cn/news/detail-843407.html
總結(jié)
? ? ? ? 現(xiàn)在是 2024-3-9 16:25 ,數(shù)倉建模的知識終于學(xué)完了,用了近一周。理論的學(xué)習(xí)還是非常有必要的,這是我現(xiàn)在越發(fā)體會到的。就比如最近背的面試題,你要說寫代碼用的上嗎?那一般指定用不上,但是對你不論是理解代碼還是二次開發(fā)都是必須熟悉的。就像 MapReduce 程序工作會讓我們?nèi)憜幔强隙ú粫?,都是?Hive SQL ,但是不了解行嗎?就像 Flink 的水位線不去了解它怎么做到精確一次背后的原理,只會跟著視頻敲代碼那也絕對屁用沒有。所以很多人說 Java 網(wǎng)上 SSM 十幾個小時速成,我看完多練練就精通了,但是 SSM 背后的反射機(jī)制、注解、代理模式、單例模式、工廠模式這些東西自己不懂那只能說你的上限也就到這了。文章來源地址http://www.zghlxwxcb.cn/news/detail-843407.html
到了這里,關(guān)于離線數(shù)倉(五)【數(shù)據(jù)倉庫建?!康奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!