文章目錄
- 前言
- 什么是觸發器(Trigger)?
- 觸發器的特點
- MySQL中觸發器的用法
- 創建
- NEW 與 OLD
- 舉例
- 其他操作
- 注意事項
- 后續內容
- 參考目錄
前言
閱讀本文前請注意最后編輯時間,文章內容可能與目前最新的技術發展情況相去甚遠。歡迎各位評論與私信,指出錯誤或是進行交流等。
什么是觸發器(Trigger)?
觸發器(Trigger)是數據庫中的一種特殊存儲程序,它綁定到某張表(或視圖)上,并在特定的數據庫操作(如 INSERT、UPDATE 或 DELETE)發生時自動執行預定義的操作。觸發器無需手動調用,是一種事件驅動的機制。
觸發器的特點
-
自動執行:一旦滿足觸發條件,觸發器會在相關操作執行之前或之后自動運行。
-
綁定表:每個觸發器都與特定的表綁定,只對該表的操作有效。
-
觸發器類型包括:
AFTER DELETE:在刪除數據之后執行。
BEFORE DELETE:在刪除數據之前執行。
AFTER UPDATE:在更新數據之后執行。
BEFORE UPDATE:在更新數據之前執行。
AFTER INSERT:在插入數據之后執行。
BEFORE INSERT:在插入數據之前執行。 -
適用范圍:
觸發器作用于每一行操作(FOR EACH ROW),或是整個語句的操作(FOR EACH STATEMENT,但在 MySQL 中不支持)。
MySQL中觸發器的用法
創建
DELIMITER $$CREATE TRIGGER trigger_name { BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON table_name FOR EACH ROW
BEGIN執行語句
END $$DELIMITER ;
NEW 與 OLD
MySQL中定義了NEW和OLD,用來表示觸發器的所在表中,觸發了觸發器的那一行數據。引用觸發器中發生變化的記錄內容,具體地:
觸發器類型 | 觸發器類型NEW和OLD的使用 |
---|---|
INSERT型觸發器 | NEW表示將要或者已經新增的數據 |
UPDATE型觸發器 | OLD表示修改之前的數據,NEW表示將要或已經修改后的數據 |
DELETE 型觸發器 | OLD表示將要或者已經刪除的數據 |
使用方法:
NEW.columnName (columnName為相應數據表某一列名)
OLD.columnName
舉例
下面是一個用于清理數據的觸發器代碼示例,為了使大家更好的理解觸發器的使用,下面將為大家分析每句代碼的作用以及使用方法。
(題目:在社區表community中,當新增新的小區后;觸發事件為當前新增小區這個insert操作。當新增小區樓棟數量 大于20棟 且 住戶不低于150人,則在訪客記錄表manual_record中 刪除 離開時間(out_time)距現在是一年以前 且 所有已離開的訪客記錄 (is_leave=1))
DELIMITER $$
?
CREATE TRIGGER update_is_leave_cleanup
AFTER INSERT ON community
FOR EACH ROW
BEGIN-- 檢查新增小區樓棟數量是否 大于20棟 且 住戶是否不低于150人IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN-- 刪除所有離開時間超過一年的訪客記錄DELETE FROM manual_recordWHERE is_leave = 1AND out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);END IF;
END$$
?
DELIMITER ;
CREATE TRIGGER update_is_leave_cleanup:創建一個名為 update_is_leave_cleanup 的觸發器。
AFTER INSERT:表示在 community表執行 INSERT操作后觸發該觸發器。
ON community:觸發器綁定到 community表。
FOR EACH ROW:觸發器對 insert 操作的每一行都生效(逐行觸發)。
BEGIN 和 END 標志觸發器主體,表示觸發器的邏輯操作。
-- 檢查新增小區樓棟數量是否 大于20棟 且 住戶是否不低于150人IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN
- NEW.字段名:表示插入的新值。
- 條件含義:
檢查新增小區樓棟數量是否 大于20棟 且 住戶是否不低于150人。
如果 NEW.term_count > 20 且 NEW.per_count >= 150,說明當前新增記錄符合條件。
DELETE FROM manual_record
WHERE is_leave = 1AND out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);
-
條件 1:is_leave = 1:
僅刪除已經離開的記錄。 -
條件 2:out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR):
out_time 是記錄的離開時間。
DATE_SUB(NOW(), INTERVAL 1 YEAR) 計算當前時間減去 1 年的日期。
如果 out_time 早于一年前,則認為該記錄已過期,刪除之。
END IF; 結束條件語句。END $$ 標志觸發器邏輯結束。DELIMITER $$ 重置分隔符
其他操作
# 查看觸發器
show triggers;# 刪除觸發器
drop trigger if exists trigger_name;# 需要注意的是,MySQL 不支持直接禁用單個觸發器,但可以通過禁用整個表的觸發器來達到類似的效果。
# 禁用所有觸發器(全局禁用)
SET GLOBAL DISABLE_TRIGGERS = 1;# 啟用所有觸發器(全局啟用)
SET GLOBAL DISABLE_TRIGGERS = 0;
注意事項
-
觸發器性能:如果表數據量大,使用觸發器可能會影響性能。假設觸發器每次執行花費1s, insert table 500條數據,那么就需要觸發500次觸發器,光是觸發器執行的時間就花費了500s,而insert500條數據一共是1s,那么這個insert的效率就非常低了。
-
事務支持:如果 UPDATE 操作失敗,觸發器邏輯也不會執行。
-
調試觸發器:可以通過啟用 MySQL 日志或手動檢查數據變化來調試觸發器。
-
數據備份:刪除記錄操作是不可逆的,在執行觸發器前確保數據已備份。
-
MYSQL中觸發器中不能對本表進行insert,update,delete操作,以免遞歸循環觸發
-
觸發器是針對每一行的;在增刪改非常頻繁的表上使用觸發器會非常消耗資源。
后續內容
關于MySQL已經是非常成熟的技術了,且優秀的博文和視頻非常之多,所以就不打算做重復的工作。貼一些優秀的內容共同學習即可
MySQL索引:https://blog.csdn.net/justry_deng/article/details/81458470
https://blog.csdn.net/qq_35190492/article/details/109257302
https://blog.csdn.net/2401_85373732/article/details/145061201
MySQL事務:https://blog.csdn.net/weixin_58376680/article/details/136993032
https://blog.csdn.net/qq_56880706/article/details/122653735
MySQL鎖:https://blog.csdn.net/qq_44700578/article/details/139912042
MySQL優化:https://blog.csdn.net/yuan2019035055/article/details/122310447(SQL優化、索引優化、鎖機制、主從復制)
https://blog.csdn.net/xiaofeng10330111/article/details/105360974(索引優化)
參考目錄
https://www.bilibili.com/video/BV1iF411z7Pu
https://blog.csdn.net/Future_yzx/article/details/144633142
https://blog.csdn.net/weixin_42571280/article/details/141650739