複寫將資料從「發行者」複製到多個「訂閱者」,透過「散發者」協調,確保異地資料一致性。三大核心角色:
| 類型 | 適用場景 | 同步機制 | 延遲 |
|---|---|---|---|
| 快照式複寫 | 資料量小、變動少、定期整批更新 | 定期產生完整快照覆蓋目標 | 高(依排程) |
| 交易式複寫 | 高即時性需求、OLTP 系統 | 以交易為單位,近乎即時推送變更 | 極低(秒級) |
| 合併式複寫 | 離線/行動裝置、雙向寫入 | 追蹤雙端變更,同步時合併衝突解決 | 中(依同步頻率) |
當無法使用複寫(跨版本、異構、頻寬受限)時,可採用「觸發器標記變更 + 連結伺服器 + 排程作業」架構:
-- 1. 本地表加狀態欄位
ALTER TABLE [user] ADD [state] BIT NULL; -- NULL=新增, 1=修改, 0=同步完成
-- 2. 觸發器自動維護 state
CREATE TRIGGER t_state ON [user] AFTER UPDATE AS
UPDATE u SET state = 1
FROM [user] u JOIN inserted i ON u.id = i.id
WHERE u.state IS NOT NULL;
-- 3. 建立連結伺服器
EXEC sp_addlinkedserver 'srv_lnk', '', 'SQLOLEDB', '遠端IP';
EXEC sp_addlinkedsrvlogin 'srv_lnk', 'false', NULL, 'sa', '密碼';
-- 4. 同步存儲程序(刪除/新增/更新三合一)
CREATE PROC p_synchro AS
BEGIN
-- 刪除遠端已不存在的資料
DELETE FROM srv_lnk.test.dbo.[user]
WHERE id NOT IN (SELECT id FROM [user]);
-- 新增本地標記為 NULL 的資料
INSERT INTO srv_lnk.test.dbo.[user] (id, number, name)
SELECT id, number, name FROM [user] WHERE state IS NULL;
-- 更新本地標記為 1 的資料
UPDATE r SET number = l.number, name = l.name
FROM srv_lnk.test.dbo.[user] r JOIN [user] l ON r.id = l.id
WHERE l.state = 1;
-- 重置本地標記
UPDATE [user] SET state = 0 WHERE ISNULL(state,1) = 1;
END;
-- 5. 建立 SQL Agent 作業每日定時執行 p_synchro