拉鍊表和流水錶

拉鍊表流水錶都是爲了記錄數據的歷史信息。

只是數據粒度的不同。

流水錶精確到每天的每一條變化都記錄其歷史。而拉鍊表的粒度可控,一般選擇每天爲粒度,即每天的最終變化才記錄。

所以理解了拉鍊表,自然就知道流水錶了。

下面通過一個例子理解一下拉鍊表

2019-9-10

用戶id 金額 時間
001 500 2019-9-10 12:00:00
002 600 2019-9-10 7:00:00
003 700 2019-9-10 16:00:00

此時的拉鍊表

用戶id 金額 時間 到期時間
001 500 2019-9-10 12:00:00 9999-99-99 99:99:99
002 600 2019-9-10 7:00:00 9999-99-99 99:99:99
003 700 2019-9-10 16:00:00 9999-99-99 99:99:99
這裏的到期日期只是一個標誌,用來標記這個數據是當前的數據還是歷史數據。
9999-99-99 99:99:99 這個時間是可以自定義的。甚至不用時間用任意自定義的標識符都行。

2019-9-11

用戶id 金額 時間
001 500 2019-9-11 12:00:00
002 200 2019-9-11 17:00:00
003 800 2019-9-11 10:00:00

變更記錄

用戶id 金額 時間 備註
002 400 2019-9-11 10:00:00 取款200
003 800 2019-9-11 10:00:00 存款100
002 200 2019-9-11 17:00:00 取款200

此時的拉鍊表

用戶id 金額 時間 到期時間
001 500 2019-9-10 12:00:00 9999-99-99 99:99:99
002 600 2019-9-10 7:00:00 2019-9-11 17:00:00
002 200 2019-9-11 17:00:00 9999-99-99 99:99:99
003 700 2019-9-10 16:00:00 2019-9-11 10:00:00
003 800 2019-9-11 10:00:00 9999-99-99 99:99:99

可以看到,9-11號這天,002號用戶有兩條交易記錄,最後也只記錄了當天最終的變化一條記錄。這就是以天爲粒度的拉鍊表。如果有很多天都變化,拉鍊表中就會有多條記錄。

如何得到拉鍊表?

我們可以通過Cannl監聽mysql的數據變化,然後每天做一個合併,再同步到hdfs上。

提一下,變更記錄一般是在mysql端處理(合併)的。所以到了ods層,每個用戶的變更記錄已經只有一條了。

表結構

-- 用戶賬戶表
create table if not exists zzy.account_info(
    id string,
    money int,
    in_time string  -- 進賬時間
)
row format delimited fields terminated by ' ';

-- 賬戶變更表
create table if not exists zzy.account_change_detail(
    id string,
    money int,
    in_time string, -- 交易時間
    `comment` string -- 交易細節
)
row format delimited fields terminated by ' ';

-- 賬戶拉鍊表
create table if not exists zzy.account_zipper(
    id string,
    money int,
    in_time string, -- 進賬時間
    out_time string -- 這條記錄過期時間
)
row format delimited fields terminated by ' ';

更新拉鍊表

insert overwrite table zzy.account_zipper
select -- 更新這才變更的記錄
a.id,
a.money,
a.in_time,
(
case 
  when out_time="9999-99-99 99:99:99" and b.id is not null
  then b.in_time
  else out_time --如果沒匹配上說明是歷史記錄 原樣保留就行
end
) out_time
from zzy.account_zipper a
left join zzy.account_change_detail b
on a.id=b.id
union
select -- 追加新記錄
id,
money,
in_time,
'9999-99-99 99:99:99' out_time
from zzy.account_change_detail
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章