首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 觸發器實現跨庫表數據同步:實戰代碼與工具避坑指南

     編輯:MySQL 資料庫相關知識

業務場景

同一實例下兩個數據庫 a、b,各有一張結構相同的表 table1(id, val)、table2(id, val)。需求:a.table1 更新時,自動將變更同步到 b.table2。

觸發器完整代碼

DELIMITER $$
CREATE TRIGGER `a`.`trg_sync_table1_to_table2`
BEFORE UPDATE ON `a`.`table1`
FOR EACH ROW
BEGIN
    -- 僅當主鍵 id 發生變化時同步(演示邏輯,實際常同步 val 等業務字段)
    IF NEW.id <> OLD.id THEN
        UPDATE `b`.`table2`
        SET `b`.`table2`.id = NEW.id
        WHERE `b`.`table2`.val = OLD.val;
    END IF;
END$$
DELIMITER ;

關鍵點解析

  • BEFORE UPDATE:在主表行鎖持有期間執行,同步操作與主表更新在同一事務,保證原子性——主表回滾則同步自動回滾。
  • NEW/OLD:引用新/舊行數據,NEW.id 為更新後值,OLD.val 為更新前值。
  • DELIMITER $$:避免觸發器體內分號提前結束創建語句。
  • 跨庫引用需完整限定名:`b`.`table2`,且當前用戶需擁有兩庫相應權限。

工具避坑指南

擴展:同步 INSERT/DELETE

-- 同步 INSERT
CREATE TRIGGER `a`.`trg_ins_table1`
AFTER INSERT ON `a`.`table1`
FOR EACH ROW
    INSERT INTO `b`.`table2` (id, val) VALUES (NEW.id, NEW.val);

-- 同步 DELETE
CREATE TRIGGER `a`.`trg_del_table1`
AFTER DELETE ON `a`.`table1`
FOR EACH ROW
    DELETE FROM `b`.`table2` WHERE id = OLD.id;

注意:AFTER 觸發器在主表操作成功提交後執行,若同步目標庫不可用會報錯但主表已提交,需業務層面容忍或改用異步同步(Canal/Maxwell + MQ)。

性能與限制提示

  • 觸發器屬於同步阻塞操作,高寫入 TPS 表慎用,會增加主表更新延遲。
  • MySQL 觸發器不支持調用存儲過程中含有動態 SQL 或事務控制語句(COMMIT/ROLLBACK)。
  • 大批量導數據時建議暫用 SET SESSION sql_log_bin=0 禁用 binlog 或 DISABLE TRIGGER(8.0+),導完再開啟。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
工具問題解決
phpMyAdmin創建觸發器頻繁報語法錯誤,無可視化向導先在支持觸發器可視化的客戶端(如 SQLyog、DBeaver、DataGrip)創建並測試,再複製 SQL 到 phpMyAdmin 執行
SQLyog (Java 客戶端)界面友好、可視化創建觸發器、自動處理 DELIMITER推薦作為開發調試首選工具
MySQL Workbench官方工具、ER 圖、觸發器/存儲過程編輯器完善生產環境 DBA 首選