舉乙個具體的應用場景,來設計並實現乙份拉鍊表,最後並通過一些例子說明如何使用我們設計的這張表(因為現在hive的大規模使用,我們會以hive場景下的設計為例)。
拉鍊表的使用場景
為什麼使用拉鍊表
拉鍊表的設計和實現
在hive中實現拉鍊表
拉鍊表和流水表
查詢效能
總結所謂拉鍊,就是記錄歷史
使用者id 使用者名稱 出生日期 住址
114 張三 1988-09-08 北京市朝陽區
使用者體驗不好
使用者id 使用者id 使用者名稱 出生日期 住址
9527 114 張三 1988-09-08 北京市朝陽區
修改後:
編號 使用者id 使用者名稱 出生日期 住址
9527 114 張三 1988-09-08 北京市朝陽區
9528 114 張三 1992-09-08 北京市海淀區
編號 使用者id 使用者名稱 出生日期 住址
9527 114 張三 1988-09-08 北京市朝陽區
修改後
編號 使用者id 使用者名稱 出生日期 出生日期2 住址 現住址
9527 114 張三 1988-09-08 1992-09-08 北京市朝陽區 北京市海淀區
那麼對於這種表我該如何設計呢?下面有幾種方案可選:
方案二拉鍊表
如何設計一張拉鍊表
下面我們來舉個栗子詳細看一下拉鍊表,現在以使用者的拉鍊表來說明。
我們先看一下在mysql關係型資料庫裡的user表中資訊變化。
在2017-01-01這一天表中的資料是:
註冊日期 使用者編號 手機號碼
2017-01-01 001 111111
2017-01-01 002 222222
2017-01-01 003 333333
2017-01-01 004 444444
在2017-01-02這一天表中的資料是, 使用者002和004資料進行了修改,005是新增使用者:
註冊日期 使用者編號 手機號碼 備註
2017-01-01 001 111111
2017-01-01 002 233333 (由222222變成233333)
2017-01-01 003 333333
2017-01-01 004 432432 (由444444變成432432)
2017-01-02 005 555555 (2017-01-02新增)
在2017-01-03這一天表中的資料是, 使用者004和005資料進行了修改,006是新增使用者:
註冊日期 使用者編號 手機號碼 備註
2017-01-01 001 111111
2017-01-01 002 233333
2017-01-01 003 333333
2017-01-01 004 654321 (由432432變成654321)
2017-01-02 005 115115 (由555555變成115115)
2017-01-03 006 666666 (2017-01-03新增)
如果在資料倉儲中設計成歷史拉鍊表儲存該錶,則會有下面這樣一張表,這是最新一天(即2017-01-03)的資料:
註冊日期 使用者編號 手機號碼 t_start_date t_end_date
2017-01-01 001 111111 2017-01-01 9999-12-31
2017-01-01 002 222222 2017-01-01 2017-01-01
2017-01-01 002 233333 2017-01-02 9999-12-31
2017-01-01 003 333333 2017-01-01 9999-12-31
2017-01-01 004 444444 2017-01-01 2017-01-01
2017-01-01 004 432432 2017-01-02 2017-01-02
2017-01-01 004 654321 2017-01-03 9999-12-31
2017-01-02 005 555555 2017-01-02 2017-01-02
2017-01-02 005 115115 2017-01-03 9999-12-31
2017-01-03 006 666666 2017-01-03 9999-12-31
說明
而且我們要確定拉鍊表的時間粒度,比如說拉鍊表每天只取乙個狀態
,也就是說如果一天有3個狀態變更,我們只取最後乙個狀態,這種天粒度的表其實已經能解決大部分的問題了。
另外,補充一下每日的使用者更新錶該怎麼獲取,據筆者的經驗,有3種方式拿到或者間接拿到每日的使用者增量,因為它比較重要,所以詳細說明:
create external table ods.user (
user_num string comment '使用者編號',
mobile string comment '手機號碼',
reg_date string comment '註冊日期'
comment '使用者資料表'
partitioned by (dt string)
row format delimited fields terminated by '\t' lines terminated by '\n'
stored as orc
location '/ods/user'
;)
create external table ods.user_update (
user_num string comment '使用者編號',
mobile string comment '手機號碼',
reg_date string comment '註冊日期'
comment '每日使用者資料更新表'
partitioned by (dt string)
row format delimited fields terminated by '\t' lines terminated by '\n'
stored as orc
location '/ods/user_update'
;)
create external table dws.user_his (
user_num string comment '使用者編號',
mobile string comment '手機號碼',
reg_date string comment '使用者編號',
t_start_date ,
t_end_date
comment '使用者資料拉鍊表'
row format delimited fields terminated by '\t' lines terminated by '\n'
stored as orc
location '/dws/user_his'
;)
insert overwrite table dws.user_his
select * from
( select a.user_num,
a.mobile,
a.reg_date,
a.t_start_time,
case
when a.t_end_time =
'9999-12-31' and b.user_num is not null then '2017-01-01'
else a.t_end_time
end as t_end_time
from dws.user_his as a
left join ods.user_update as b
on a.user_num = b.user_num
union
select c.user_num,
c.mobile,
c.reg_date,
'2017-01-02' as t_start_time,
'9999-12-31' as t_end_time
from ods.user_update as c
) as t
參考自資料倉儲之拉鍊表(原理、設計以及在hive中的實現)
拉鍊表設計
一 建立拉鍊表 1 假如首日是2022 02 24,首先將資料從ods層載入到dim層,分割槽日期和結束日期都為9999 00 00 2 第二日2022 02 25,一部分使用者新增變化,需要把新增的和變化的裝載到dim層,分割槽結束日期是9999分割槽,但要注意9999分割槽有一部分過期資料 過期...
Hive拉鍊表設計方案
定義 所謂拉鍊,就是記錄歷史。記錄乙個事物從開始,一直到當前狀態的所有變化的資訊。使用場景 舉個栗子,現有一張內含1000萬資料的訂單表,每天都有100左右的訂單狀態會變化,因業務需求要回溯某個歷史節點的一筆訂單的狀態。現有兩種處理方式 1.比較原始的做法,對每天的資料做切片表,檢視對應時間的切片表...
數倉分層設計
介紹資料分層的作用 提出一種通用的資料分層設計,以及分層設計的原則 舉出具體的例子說明 提出可落地的實踐意見 0x01 資料分層?為什麼要設計資料分層?這應該是資料倉儲同學在設計資料分層時首先要被挑戰的問題,類似的問題可能會有很多,比如說 為什麼要做資料倉儲?為什麼要做元資料管理?為什麼要做資料質量...