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

MySQL 觸發器完整指南:語法、實戰案例、優缺點與最佳實踐

     編輯:MySQL 資料庫相關知識

什麼是觸發器

觸發器 是與表關聯的命名資料庫物件,當表發生 INSERT/UPDATE/DELETE 事件時自動執行。它是特殊的儲存過程,不由應用呼叫,由資料庫事件驅動。

語法結構

CREATE TRIGGER `trigger_name`
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON `tbl_name` FOR EACH ROW
BEGIN
    -- 觸發器主體:可使用 NEW、OLD 伪列
    -- NEW:新行(INSERT/UPDATE)
    -- OLD:舊行(UPDATE/DELETE)
END;

關鍵規則

  • 同一表、同一事件、同一時機(BEFORE/AFTER)只能有一個觸發器。
  • BEFORE 可修改 NEW 值(如自動填充、驗證)。
  • AFTER 不可修改 NEW,常用於同步其他表、日誌、統計。
  • 觸發器內發生錯誤會導致原語句回滾(原子性)。
  • 不支援 CALL 觸發器,不支援顯式事務控制。

實戰案例:用戶表與評論表冗余字段同步

表結構

CREATE TABLE `user` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(50) NOT NULL,
  `sex` TINYINT DEFAULT 0
) ENGINE=InnoDB;

CREATE TABLE `comment` (
  `c_id` INT AUTO_INCREMENT PRIMARY KEY,
  `u_id` INT NOT NULL,
  `name` VARCHAR(50) NOT NULL,  -- 冗余字段,避免 JOIN
  `content` VARCHAR(1000)
) ENGINE=InnoDB;

觸發器 1:用戶改名同步到評論表

DELIMITER $$
DROP TRIGGER IF EXISTS `trg_user_name_sync`$$
CREATE TRIGGER `trg_user_name_sync`
AFTER UPDATE ON `user` FOR EACH ROW
BEGIN
    IF NEW.`name` <> OLD.`name` THEN
        UPDATE `comment` SET `name` = NEW.`name` WHERE `u_id` = OLD.`id`;
    END IF;
END$$
DELIMITER ;

觸發器 2:用戶刪除時級聯刪除評論

DELIMITER $$
DROP TRIGGER IF EXISTS `trg_user_delete_cascade`$$
CREATE TRIGGER `trg_user_delete_cascade`
BEFORE DELETE ON `user` FOR EACH ROW
BEGIN
    DELETE FROM `comment` WHERE `u_id` = OLD.`id`;
END$$
DELIMITER ;

測試驗證

-- 初始資料
INSERT INTO `user` (`name`) VALUES ('張映'), ('tank');
INSERT INTO `comment` (`u_id`, `name`, `content`) VALUES
(1, '張映', '觸發器測試'), (1, '張映', '解決字段冗余'), (2, 'tank', '使代碼更簡單');

-- 測試改名
UPDATE `user` SET `name` = '蒼鷹' WHERE `id` = 1;
SELECT * FROM `comment` WHERE `u_id` = 1;  -- name 應全變為 '蒼鷹'

-- 測試刪除用戶
DELETE FROM `user` WHERE `id` = 1;
SELECT * FROM `comment` WHERE `u_id` = 1;  -- 應為空

查看與管理

SHOW TRIGGERS;
SHOW CREATE TRIGGER `trg_user_name_sync`;
DROP TRIGGER IF EXISTS `trg_user_name_sync`;

優缺點深度分析

優點缺點/風險
自動性:應用層無感知,減少代碼耦合隱蔽性:邏輯在 DB 層,難追蹤、除錯
資料完整性:原子性保證,避免「改了主表沒改從表」效能:大量 DML 時觸發器開銷累積,可能成瓶頸
集中維護:業務規則集中 DB,多應用共享遷移困難:跨資料庫/異構遷移需重寫
審計/日誌:自動記錄變更軌跡鎖爭用:觸發器內操作其他表會延長鎖持有時間

最佳實踐建議

  1. 僅用於「資料完整性」相關邏輯:冗余同步、級聯刪除、審計日誌、自動編號。
  2. 避免複雜業務計算、外部呼叫、發送郵件/HTTP。
  3. 命名規範:trg_{table}_{event}_{purpose},如 trg_order_after_insert_audit。
  4. 文檔化:在資料庫字典中記錄每個觸發器用途、觸發條件、影響表。
  5. 效能監控:performance_schema.triggers、慢查詢日誌關聯分析。
  6. 替代方案評估:應用層事件驅動、CDC (Debezium)、物化視圖、定時任務同步。

結語

觸發器是資料庫層面的「事件總線」,用得好能簡化應用、保證一致性;用不好會變成隱形效能殺手與維護噩夢。克制使用、文檔先行、效能監控,是駕馭觸發器的鐵律。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved