大量資料同步的核心在於**「僅同步變更」**。本文比較六種取得差異資料的方法,依實作複雜度、即時性、資源消耗、適用場景評分。
| 方法 | 原理 | 即時性 | 結構變更 | 二次處理 | 維護成本 | 適用場景 |
|---|---|---|---|---|---|---|
| 1. 時間戳欄位 (CreatedOn/ChangedOn) | 應用層維護建立/修改時間 | 近即時 | 需加欄位 | 支援 | 中 (開發需自律) | 一般業務表、開發可控 |
| 2. 觸發器 (Trigger) | INSERT/UPDATE/DELETE 寫入變更表 | 即時 | 無 | 支援 (觸發器內) | 中高 (觸發器除錯難) | 需即時、需二次處理、不可動表結構 |
| 3. SQL Server 內建複寫 | 記錄讀取器擷取交易 | 秒級 | 無 | 難 (標準複寫無攔截點) | 高 (拓撲複雜) | 標準同步、異構、高可用 |
| 4. TIMESTAMP / ROWVERSION 欄位 | 資料庫自動遞增版本號 | 近即時 | 需加欄位 | 不支援 (僅偵測變更) | 低 | 高併發、需精確版本控制 |
| 5. DML 語句記錄與重放 | 每日擷取 UPDATE/DELETE 重放 | 批次 (每日) | 無 | 支援 (重放前轉換) | 中 (需解析 SQL) | 網路差、非即時、需轉換邏輯 |
| 6. BINARY_CHECKSUM | 列級雜湊值偵測任意欄位變更 | 近即時 | 無 | 支援 (比對前計算) | 低 | 無法加欄位、需偵測部分欄位、無 Timestamp |
-- 1. 基準表
CREATE TABLE SyncBaseline (PK INT PRIMARY KEY, ChkSum BIGINT);
INSERT INTO SyncBaseline
SELECT PK, BINARY_CHECKSUM(Col1, Col2, Col3) FROM SourceTable;
-- 2. 偵測變更
SELECT s.PK
FROM SourceTable s
JOIN SyncBaseline b ON s.PK = b.PK
WHERE BINARY_CHECKSUM(s.Col1, s.Col2, s.Col3) <> b.ChkSum;
-- 3. 同步後更新基準
MERGE SyncBaseline b
USING (SELECT PK, BINARY_CHECKSUM(Col1, Col2, Col3) AS ChkSum FROM SourceTable) s
ON b.PK = s.PK
WHEN MATCHED THEN UPDATE SET b.ChkSum = s.ChkSum
WHEN NOT MATCHED THEN INSERT (PK, ChkSum) VALUES (s.PK, s.ChkSum);
BINARY_CHECKSUM **忽略** text, ntext, image, cursor, sql_variant 等不可比較型別欄位,若需監控這些欄位請改用 Trigger 或 CDC。TIMESTAMP/ROWVERSION 為資料庫全域單調遞增,**非壹對壹對應列版本**,僅能判斷「表自上次同步後是否有變更」,需配合主鍵定位具體列。「僅同步變更」是大量同步的鐵律。根據「能否動結構、即時性要求、二次處理需求、資源限制」四維度選擇最適策略,並建立基準表/變更表作為同步錨點,即可將同步量壓縮至全量的 1~5%,大幅降低網路與 IO 壓力。