MySQL觸發器的使用規則

 觸發器能夠在執行語句前或執行後觸發其餘 SQL 代碼運行。觸發器能夠讀取觸發語句改變了哪些數據,可是沒有返回值。所以可使用觸發器增強業務邏輯的約束而不須要在應用程序寫對應的代碼。數據庫

從上述描述能夠看到,觸發器能夠簡化應用程序的邏輯而且能夠提高性能,這是由於使用觸發器減小了應用程序和服務端的交互次數。同時,觸發器有助於完成自動更新歸一化和統計數據。例如,咱們可使用觸發器自動統計交易訂單總金額,訂單數及平均客單價。 然而,MySQL 的觸發器的應用場合也十分有限,若是你使用過其餘數據庫產品的觸發器,不要覺得 MySQL 也能實現相同的功能,例如:緩存

每一個數據表的單一事件只能有一個觸發器,也就是說對於 AFTER INSERT 這樣的事件來講,不能同時有超過1個的觸發器。
MySQL 只支持行級別的觸發器,也就是隻能按 FOR EACH ROW 這種方式使用觸發而不是整個 SQL 語句,這對於大量數據的操做而言會比較低效。MySQL 的觸發器只能按下面的形式編寫:
CREATE TRIGGER 觸發器名 BEFORE|AFTER 觸發事件
ON 表名 FOR EACH ROW
BEGIN併發

執行語句列表;

END
執行語句列表支持單條或多條語句,下面是一個多條語句的示例:ide

DELIMITER $$
CREATE TRIGGER user_create_log AFTER INSERT ON t_users FOR EACH ROW
BEGIN
DECLARE log_info VARCHAR(40)character set utf8;
DECLARE description VARCHAR(20) character set遊戲http://www.cungun.com utf8;#後面發現中文字符編碼出現亂碼,這裏設置字符集
SET description = " is created";
SET log_info = CONCAT(NEW.user_name, description); #函數CONCAT能夠將字符串鏈接
INSERT INTO logs(log) values(log_info);
END $$函數

DELIMITER ;
觸發器可能致使服務端實際執行的工做不可預測,一個簡單的語句可能致使服務端作大量不可見的工做。例如,若是一個觸發器更新了 一個相關的表,可能致使受影響的行數加倍。
觸發器難以調試,而且一旦引入了觸發器,很難分析性能瓶頸。
觸發器會致使潛在的鎖等待和死鎖。若是觸發器失敗了,遊戲源查詢也會失敗。若是沒有意識到觸發器的存在,這類玩呢提很難發現。
大多數限制中,最大的限制是 FOR EACH ROW 的設計,這有時候致使觸發器無法用於維護統計和緩存表,這是由於這可能很慢。使用觸發器的主要理由是相比定時同步更新,觸發器能夠一致保持數據的一致性。 觸發器也無法保證原子性。例如,更新 MyISAM 數據表的觸發器在源 SQL 語句出錯後,沒法回滾。並且,觸發器自身也可能都只錯誤。若是咱們使用了 AFTER UPDATE 基於 MyISAM 數據表去更新另外一個表。若是觸發器有個致使第二張表操做失敗的錯誤,那對於第一張表的操做不會回滾。性能

InnoDB 的觸發器相關的操做,包括源語句都在同一個事務中,所以是知足原子性的。然而,若是使用InnoDB 的觸發器去與另外一張表校驗數據一致性的時候,這個時候若是不當心的話可能致使不正確的結果。例如,假設須要使用觸發器模擬外鍵,可使用 BEFORE INSERT觸發器驗證另外一張表是否存在對應的記錄,可是若是在觸發器讀取另外一張表數據的時候不使用 SELECT FOR UPDATE的話,則因爲併發性性問題可能致使錯誤的結果。 雖然觸發器有些缺陷,可是這並不意味着不能用。相反,觸發器自己也是有用的,尤爲是對於約束,系統維護任務和保持統計數據保持最新。大數據

也可使用觸發器記錄數據行的變化。這樣即使是離線手動操做數據庫的記錄(如修復錯誤數據)也可以被記錄下來。可是,須要注意的是對於往其餘自增主鍵表插入數據時要當心,這對於複製性的語句表現會有問題,由於自增值對於兩個相同的副本值並不一樣。編碼

觸發器在有限的場合可以發揮其優點,好比統計數據、數據表變動日誌等。可是也會有一些缺陷,好比大數據量的更新因爲逐行觸發,會下降效率。還有就是,MyISAM 引擎沒法保障原子性。所以,要根據應用場景是否要是有觸發器。spa

相關文章
相關標籤/搜索