郵箱系統(ExtMail)與論壇系統 數據庫分離,需實現:用戶在郵箱 Web 端修改密碼/郵箱,自動同步到論壇用戶表,僅同步 username、password、email 三欄,其餘欄位走默認值。
必須先 USE 觸發源資料庫,再創建觸發器,否則報錯 ERROR 1146: Table doesn't exist。觸發器定義在源庫,操作目標庫表需跨庫引用 目標庫.表名。
USE `extmail`;
DELIMITER //
CREATE TRIGGER `add_bbsuser`
AFTER INSERT ON `extmail`.`mailbox`
FOR EACH ROW
BEGIN
INSERT INTO `xiuno_bbs`.`bbs_user` (`username`, `password`, `email`)
VALUES (NEW.`name`, NEW.`password`, NEW.`username`);
END//
DELIMITER ;
USE `extmail`;
DELIMITER //
CREATE TRIGGER `update_bbsuser`
AFTER UPDATE ON `extmail`.`mailbox`
FOR EACH ROW
BEGIN
UPDATE `xiuno_bbs`.`bbs_user`
SET `username` = NEW.`name`,
`password` = NEW.`password`
WHERE `email` = NEW.`username`;
END//
DELIMITER ;
USE `extmail`;
DELIMITER //
CREATE TRIGGER `delete_bbsuser`
AFTER DELETE ON `extmail`.`mailbox`
FOR EACH ROW
BEGIN
DELETE FROM `xiuno_bbs`.`bbs_user`
WHERE `email` = OLD.`username`;
END//
DELIMITER ;
-- 查看所有觸發器
SHOW TRIGGERS\G
-- 或查特定庫
SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA='extmail';
-- 刪除觸發器
DROP TRIGGER IF EXISTS `add_bbsuser`;
| 坑點 | 現象 | 解決 |
|---|---|---|
忘記 USE 源庫 | 創建失敗/觸發器建在錯誤庫 | 腳本開頭強制 USE source_db; |
| 跨庫引用無權限 | ERROR 1142: TRIGGER command denied | 授予 TRIGGER 權限於源庫,目標表需 INSERT/UPDATE/DELETE |
| 觸發器內事務回滾導致主操作失敗 | 主表寫入報錯 | 觸發器不支援顯式事務,異常會回滾主操作;關鍵邏輯移至應用層或用異步隊列 |
| 大批量操作觸發器效能差 | 批量導入極慢 | 大批量時禁用觸發器,改用 ETL 腳本同步 |
| 備份還原丟失觸發器 | mysqldump 預設不導出 | 加參數 --triggers(預設已開啟),還原時確保目標庫存在 |
| 方案 | 延遲 | 耦合度 | 維護成本 | 適用場景 |
|---|---|---|---|---|
| 觸發器 | 同步(同事務) | 強(DDL 需同步變更) | 中 | 低頻寫入、強一致性要求 |
| 應用雙寫 | 同步 | 中(代碼耦合) | 高 | 微服務、跨庫 |
| Binlog 訂閱 | 毫秒級異步 | 低(解耦) | 低(需中介組件) | 高併發、異構同步 |
| 定時 ETL | 分鐘~小時 | 低 | 低 | 報表、數據倉庫 |
觸發器是「資料庫層面的事件總線」,用對場景(低頻、強一致、同實例跨庫)能大幅簡化代碼;濫用於高寫入、複雜邏輯則成效能殺手。本案例中,郵箱密碼修改頻率低、同步邏輯固定,觸發器是性價比最高的選擇。