數倉 拉鍊表(原理 設計以及在Hive中的實現)

2021-10-11 13:20:38 字數 4412 閱讀 8716

舉乙個具體的應用場景,來設計並實現乙份拉鍊表,最後並通過一些例子說明如何使用我們設計的這張表(因為現在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 資料分層?為什麼要設計資料分層?這應該是資料倉儲同學在設計資料分層時首先要被挑戰的問題,類似的問題可能會有很多,比如說 為什麼要做資料倉儲?為什麼要做元資料管理?為什麼要做資料質量...