無事實的事實表概述
- 在多維數(shù)據(jù)倉庫建模中片排, 有一種事實表叫做“無事實的事實表”损离。 普通事實表中, 通常會保存若干維度外鍵和多個數(shù)字型度量谐腰, 度量是事實表的關(guān)鍵所在。 然而在無事實的事實表中沒有這些度量值棺蛛, 只有多個維度外鍵怔蚌。 表面上看, 無事實的事實表是沒有意義的旁赊, 因為作為事實表桦踊, 畢竟最重要的就是度量。 但在數(shù)據(jù)倉庫中终畅, 這類事實表有其特殊用途籍胯。 無事實的事實表通常用來跟蹤某種事件或者說明某些活動的范圍竟闪。
- 無事實的事實表可以用來跟蹤事件的發(fā)生。
- 例如杖狼, 在給定的某一天中發(fā)生的學(xué)生參加課程的事件炼蛤, 可能沒有可記錄的數(shù)字化事實, 但該事實行帶有一個包含日期蝶涩、 學(xué)生理朋、 教師、 地點绿聘、 課程等定義良好的外鍵嗽上。利用無事實的事實表可以按各種維度計數(shù)上課這個事件。
- 再比如學(xué)生注冊事件熄攘, 學(xué)校需要對學(xué)生按學(xué)期進行跟蹤兽愤。 維度表包括學(xué)期維度、 課程維度挪圾、 系維度浅萧、 學(xué)生維度、 注冊專業(yè)維度和取得學(xué)分維度等哲思, 而事實表由這些維度的主鍵組成洼畅, 事實只有注冊數(shù), 并且恒為1也殖, 因此沒有必要用單獨一列來表示土思。 這樣的事實表主要用于回答各種情況下的注冊數(shù)务热。
- 無事實的事實表還可以用來說明某些活動的范圍忆嗜, 常被用于回答“什么未發(fā)生”這樣的問題。
- 例如: 促銷范圍事實表崎岂。 通常銷售事實表可以回答如促銷商品的銷售情況捆毫, 可是無法回答的一個重要問題是: 處于促銷狀態(tài)但尚未銷售的產(chǎn)品包括哪些? 銷售事實表所記錄的僅僅是實際賣出的產(chǎn)品冲甘。 事實表行中不包括由于沒有銷售行為而銷售數(shù)量為零的行绩卤, 因為如果將包含零值的產(chǎn)品都加到事實表中, 那么事實表將變得非常巨大江醇。 這時濒憋, 通過建立促銷范圍事實表, 將商場需要促銷的商品單獨建立事實表保存陶夜, 然后通過這個促銷范圍事實表和銷售事實表即可得出哪些促銷商品沒有銷售出去凛驮。
- 為確定當(dāng)前促銷的產(chǎn)品中哪些尚未賣出, 需要兩步過程: 首先条辟, 查詢促銷無事實的事實表黔夭, 確定給定時間內(nèi)促銷的產(chǎn)品宏胯。 然后從銷售事實表中確定哪些產(chǎn)品已經(jīng)賣出去了。 答案就是上述兩個列表的差集本姥。 這樣的促銷范圍事實表只是用來說明促銷活動的范圍肩袍, 其中沒有任何事實度量。 可能有讀者會想婚惫, 建立一個單獨的促銷商品維度表能否達到同樣的效果呢氛赐? 促銷無事實的事實表包含多個維度的主鍵, 可以是日期先舷、 產(chǎn)品鹰祸、 商店、 促銷等密浑, 將這些鍵作為促銷商品的屬性是不合適的蛙婴, 因為每個維度都有自己的屬性集合。
- 促銷無事實的事實表看起來與銷售事實表相似尔破。 然而街图, 它們的粒度存在顯著差別。 假設(shè)促銷是以一周為持續(xù)期懒构, 在促銷范圍事實表中餐济, 將為每周每個商店中促銷的產(chǎn)品加載一行, 無論產(chǎn)品是否賣出胆剧。 該事實表能夠確毙跄罚看到被促銷定義的鍵之間的關(guān)系, 而與其他事件秩霍, 如產(chǎn)品銷售無關(guān)篙悯。
- 下面以銷售訂單數(shù)據(jù)倉庫為例,說明如何處理源數(shù)據(jù)中沒有度量的需求铃绒。 我們將建立一個無事實的事實表鸽照, 用來統(tǒng)計每天發(fā)布的新產(chǎn)品數(shù)量。 產(chǎn)品源數(shù)據(jù)不包含產(chǎn)品數(shù)量信息颠悬, 如果系統(tǒng)需要得到歷史某一天新增產(chǎn)品的數(shù)量矮燎, 很顯然不能簡單地從數(shù)據(jù)倉庫中得到。 這時就要用到無事實的事實表技術(shù)赔癌。 使用此技術(shù)可以通過持續(xù)跟蹤產(chǎn)品發(fā)布事件來計算產(chǎn)品的數(shù)量诞外。 可以創(chuàng)建一個只有產(chǎn)品(計什么數(shù)) 和日期(什么時候計數(shù)) 維度代理鍵的事實表。 之所以叫做無事實的事實表是因為表本身并沒有數(shù)字型度量值灾票。 這里定義的新增產(chǎn)品是指在某一給定日期峡谊, 源產(chǎn)品表中新插入的產(chǎn)品記錄, 不包括由于SCD2新增的產(chǎn)品版本記錄。 注意靖苇, 單從這個簡單需求來看席噩, 也可以通過查詢產(chǎn)品維度表獲取結(jié)果。 這里只為演示無事實的事實表的實現(xiàn)過程贤壁。
建立新產(chǎn)品發(fā)布的無事實的事實表
-
在數(shù)據(jù)倉庫模式中新建一個產(chǎn)品發(fā)布的無事實的事實表product_count_fact悼枢, 該表中只包含兩個字段, 分別是引用日期維度表和產(chǎn)品維度表的外鍵脾拆, 同時這兩個字段也構(gòu)成了無事實事實表的邏輯主鍵馒索。 下圖顯示了跟蹤產(chǎn)品發(fā)布數(shù)量的數(shù)據(jù)倉庫模式(只顯示與無事實的事實表相關(guān)的表)。
無事實的事實表.PNG - 執(zhí)行下面的腳本在數(shù)據(jù)倉庫模式中創(chuàng)建產(chǎn)品發(fā)布日期視圖及其無事的實事實表名船。
use dw;
create view
product_launch_date_dim
(
product_launch_date_sk,
product_launch_date,
month_name,
month,
quarter,
year
)
as select
distinct date_sk,
date,
month_name,
month,
quarter,
year
from
product_dim a, date_dim b
where
a.effective_date = b.date;
-- 創(chuàng)建表
create table
product_count_fact (
product_sk int,
product_launch_date_sk int
);
- 語句說明:
- 與之前創(chuàng)建的很多日期角色扮演維度不同绰上, 產(chǎn)品發(fā)布日期視圖只獲取產(chǎn)品生效日期, 而不是日期維度里的所有記錄渠驼。 因此在定義視圖的查詢語句中關(guān)聯(lián)了產(chǎn)品維度和日期維度兩個表蜈块。 product_launch_date_dim維度表是日期維度表的子集。
- 從字段定義上看迷扇, 產(chǎn)品維度表中的生效日期明顯就是新產(chǎn)品的發(fā)布日期百揭。
- 在本示例中, 無事實的事實表的數(shù)據(jù)裝載沒有行級更新需求蜓席, 所以該表使用Hive默認的文本存儲格式器一。
裝載無事實的事實表
- 下面的腳本從產(chǎn)品維度表向無事實的事實表裝載已有的產(chǎn)品發(fā)布信息。 腳本里的insert語句添加所有產(chǎn)品的第一個版本厨内, 即產(chǎn)品的首次發(fā)布日期祈秕。 這里使用Hive的窗口函數(shù)row_number正確地選取了產(chǎn)品發(fā)布時的生效日期, 而不是一個SCD2行的生效日期雏胃。
-- 裝載無事實的事實表
insert overwrite table
product_count_fact
select
product_sk,date_sk
from
(
select
a.product_sk product_sk,
b.date_sk date_sk,
row_number() over (partition by a.product_code order byb.date_sk) rn
from
product_dim a,date_dim b
where
a.effective_date = b.date
) t
where
rn = 1;
- 語句說明:
- 子查詢中內(nèi)連接產(chǎn)品維度與日期維度表请毛, 只獲取產(chǎn)品發(fā)布的日期。
- 以產(chǎn)品編碼分區(qū)丑掺, 同一個產(chǎn)品編碼的多個版本以發(fā)布日期排序获印, row_number()函數(shù)為每個版本分配序號述雾, 起別名rn街州。
- 外層查詢以rn=1作為過濾條件, 得到每個產(chǎn)品及其首次發(fā)布日期的代理鍵玻孟。
- 該語句允許多次執(zhí)行唆缴, 每次覆蓋已有數(shù)據(jù)。
- 其實利用產(chǎn)品維度表的版本字段黍翎, 更簡單的寫法如下:
-- 采用版本的方式進行開發(fā)
insert overwrite table
product_count_fact
select
a.product_sk product_sk,
b.date_sk date_sk
from
product_dim a,date_dim b
where
a.effective_date = b.date anda.version = 1;
定期裝載
- 測試腳本之后面徽,需要將腳本按照時間粒度,定時加載到Azkaban調(diào)度流中。