觸發器是資料庫層面的「事件驅動編程」,能在 DML 操作前後自動執行預定義邏輯。本文系統梳理 MySQL 觸發器的創建語法(單/多語句)、觸發時機(BEFORE/AFTER)、行級語義、元數據查看與刪除管理,並給出生產環境常見陷阱與替代方案建議。
INSERT、UPDATE、DELETE(不支援 DDL、TRUNCATE、REPLACE 直接觸發)BEFORE(寫入前,可修改 NEW 值)、AFTER(寫入後,不可修改 NEW)OLD.col(舊值,UPDATE/DELETE 可用)、NEW.col(新值,INSERT/UPDATE 可用)CREATE TRIGGER trigger_name BEFORE | AFTER INSERT | UPDATE | DELETE ON table_name FOR EACH ROW single_statement;
範例:插入前自動補全創建時間
CREATE TRIGGER trg_article_bi BEFORE INSERT ON article FOR EACH ROW SET NEW.created_at = NOW();
CREATE TRIGGER trigger_name BEFORE | AFTER INSERT | UPDATE | DELETE ON table_name FOR EACH ROW BEGIN statement_1; statement_2; ... END;
範例:更新後同步審計日誌
CREATE TRIGGER trg_user_au
AFTER UPDATE ON user
FOR EACH ROW
BEGIN
IF NEW.status <> OLD.status THEN
INSERT INTO user_status_log(uid, old_status, new_status, changed_at)
VALUES (NEW.id, OLD.status, NEW.status, NOW());
END IF;
END;
| 操作 | SQL | 關鍵輸出 |
|---|---|---|
| 列出所有觸發器 | SHOW TRIGGERS [FROM db_name] [LIKE 'pattern']; | Trigger, Event, Table, Statement, Timing, Created, sql_mode, Definer |
| 查看定義詳情 | SHOW CREATE TRIGGER trigger_name; | 完整 CREATE 語句、字符集、定義者 |
| 元數據查詢 | SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA='db'; | 可程式化篩選、導出、對比 |
| 刪除觸發器 | DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name; | 需 TRIGGER 權限 |
trg_{table}_{timing}_{event},如 trg_order_ai、trg_user_bu| 方案 | 優勢 | 劣勢 | 適用場景 |
|---|---|---|---|
| 觸發器 | 資料庫強一致性、透明於應用 | 除錯難、效能黑盒、遷移困難 | 審計日誌、必填欄位補全、簡單衍生同步 |
| 應用層領域事件 | 可見、可測、可重試、技術棧統一 | 需應用配合、最終一致性 | 複雜業務流程、跨服務同步、外部系統集成 |
| CDC (Debezium/Canal) | 零侵入、全量增量、多下游分發 | 部署複雜、延遲毫秒級 | 異構同步、數據湖入湖、緩存失效、搜尋索引構建 |
觸發器是「雙刃劍」:用得好是資料完整性的守護神,用不好是效能殺手與除錯噩夢。建議只在「單表、輕邏輯、強一致性」場景克制使用,複雜業務流轉交給應用層或 CDC 架構承擔。