1.拉鏈表理解
記錄歷史。記錄一個事物從開始,一直到當前狀態的所有變化的信息。
字段說明:
start_dt:該條記錄的生命周期開始時間
end_dt:該條記錄的生命周期結束時間
end_dt=’9999/12/31’表示該條記錄目前處于有效狀態
如果查詢當前所有有效記錄,select * from table where end_date=’9999/12/31’
如果查詢2021/10/22的歷史快照,select * from table where start_dt <=’2021/10/22’ and end_dt >=’2021/10/22’
2021/10/22的歷史快照:
2. 拉鏈表實現方式
以在hive中為例(hive表一般只能進行刪除和添加操作,不能進行update)
需要確定拉鏈表的時間粒度,比如拉鏈表每天只取一個狀態,那如果一天中有3個狀態變更,只取最后一個狀態。
2.1 需要的信息
① 數據源信息:
數據全量信息,需要用來初始化;
② 每日更新信息(在分區表中添加更新標識字段或創建每日的更新數據表)
每日更新信息的獲取方式:
在每日切片數據基礎上,取第二天數據與前一天的不同數據,標記為更新。如何比較不同,可對所有字段先進行concat,取其md5進行比較,md5值不相等時,說明有更新。(hive環境需配置md5.jar包)
(取兩天的切片數據,以md5字段做關聯(full join),若第二天數據的md5不為空,說明為最新生效樹,否則為失效數據。)
達到的效果:
對數據生效狀態進行標記(生效/失效),刪除及修改前數據為“失效”,新增及修改后數據為“生效”
數據變更形式:
數據不變、數據新增、數據刪除、數據修改(修改=刪除?新增)
若要找出具體狀態,可以用編碼字段做關鍵字段關聯(一般編碼字段不會進行修改)
(取兩天的切片數據,以編碼字段做關聯(full join),結合編碼和md5判斷數據變更形式)
2.2 添加標識字段(以編碼字段關聯)
①查看2021/10/24日數據
② 2021/10/25日數據
③ 兩個分區日期對比下,在新一日數據中添加變更標識
1:刪除,2:新增,3:修改,0:不變
實現方式:
① 前后兩個分區日期的數據對比
② 使用full join (Mysql不支持,hive支持)
③ 關聯字段為編碼obj_cd,在標識數據變更狀態時,進行全字段比較,這里是用concat函數將字段全部合并,生產環境中,一個表可能有幾十或幾百個字段,合并后的字符串長度會比較長。可以使用Md5函數,將長字符串轉化為36位編碼。(hive中需導入Md5函數的jar包)
2.3 根據標識字段,創建拉鏈表
① 首先歷史信息存在
歷史數據,其啟用時間為2021/10/24,結束時間9999/12/31
② 根據變更標識字段,最新一日的更新信息為:
③ 將更新數據與歷史數據做關聯,更新拉鏈表起止時間,并追加新數據:
實現方式:
① 在歷史數據中標記有變更的數據,更新結束時間end_dt
② 拼接更新數據(修改后數據 + 新增)