1. 概述
1.1 問題描述
使用者在定時任務進行資料同步時,如果源資料庫同時有增刪改變化,且來源表中沒有時間戳時,可以使用数据比对,但是如果資料量很大,想要更好的提高同步效率,就可以使用本文的方案進行資料同步。
時間戳:一般是記錄資料的增刪改時間。
業務時間:一般是記錄業務發生的時間(如果資料修改,業務的發生時間還是不變的)。
1.2 實現思路
由於資料表只有業務時間,因此需要使用刪除指定業務時間一部分的資料,然後再更新資料的方式。
1)獲取參數:獲取上次同步的時候,記錄的業務時間,並將其設定為參數 cur_timestamp,便於後續目標表刪除該業務時間之後的資料、來源表獲取該業務時間之後的資料。
注:cur_timestamp 初始值改到很早之前,就是初次同步全量資料。
2)同步刪除資料:刪除目標表資料中 >cur_timestamp,即目標表中業務時間晚於上次同步的業務時間的資料。
3)增量同步:獲取來源表業務時間晚於 cur_timestamp 的資料,並將增量/變化的資料同步到目標表。
4)更新時間表同步時間戳和執行記錄。 cur_timestamp 更新為特定頻率時間。注:可根據業務情況設定,比如業務一般不修改3個月前的資料。
demo 範例詳情請參見:https://demo.finedatalink.com/ 增刪改資料同步(非資料比對且無時間戳,有業務時間)
2. 操作步驟
來源表中相對於目標表修改了 1003 的 order_quantity 值,同時新增 1004 這筆資料,並且刪除了 1002 資料,如下圖所示:
其中 order_business_date 為業務時間,也就是訂單交易時間。
2.1 前提條件
建立執行記錄資料表,便於獲取每次同步的時間戳,如下圖所示:
注:兩個時間欄位初始值可以設定為一個比較早的時間,早於業務資料時間戳,以便初次同步全量資料。
2.2 獲取上次同步記錄的業務時間作為參數
1)使用「參數指派」獲取上次同步的時候記錄的業務時間,如下圖所示:
注:cur_timestamp 初始值改到很早之前,就是初次同步全量資料。
SELECT cur_timestamp
FROM `demotest`.`ETL_RECORD`
WHERE table_name='F_ORDER_NOTIMESTAMP_DATE_FROM'
並將其設定為參數 cur_timestamp,便於後續目標表刪除該業務時間之後的資料、來源表獲取該業務時間之後的資料,如下圖所示:
2.3 刪除部分資料
使用 SQL 腳本,刪除目標表資料中 >cur_timestamp,即目標表中業務時間晚於上次同步的業務時間的資料,如下圖所示:
DELETE
FROM `demotest`.`F_ORDER_NOTIMESTAMP_DATE_TARGET`
WHERE order_business_date>'${cur_timestamp}'
2.4 增量同步
建立「資料轉換」,進入編輯介面後使用DB表輸入功能,獲取來源表業務時間晚於 cur_timestamp 的資料,如下圖所示:
SELECT
*,
NOW() AS etl_time
FROM `demotest`.`F_ORDER_NOTIMESTAMP_DATE_FROM`
WHERE order_business_date>'${cur_timestamp}'
使用 DB表匯出,將增量/變化的資料同步到目標表,如下圖所示:
寫入方式設定為追加寫入並設定主鍵衝突策略,如下圖所示:
2.5 更新時間表同步時間戳和執行記錄
使用 SQL 腳本,更新時間表同步時間戳和執行記錄,cur_timestamp 更新為特定頻率時間,同時將上次同步記錄時間寫入 pre_timestamp 欄位,etl執行次數寫入 etl_time,如下圖所示:
注:可根據業務情況設定,比如業務一般不修改3個月前的資料。
UPDATE `demotest`.`ETL_RECORD`
SET
cur_timestamp=NOW() - INTERVAL 3 MONTH , ##預設3個月,按需配置
pre_timestamp='${cur_timestamp}',
etl_times=etl_times+1,
etl_last_time=NOW()
WHERE table_name='F_ORDER_NOTIMESTAMP_DATE_FROM'
2.6 效果查看
執行定時任務後,即可在目標資料表中看到同步後的資料,如下圖所示:
同時記錄表 ETL_RECORD 結果如下圖所示: