MySQL通過觸發器解決數據庫中表的行數限制詳解及實例。本站提示廣大學習愛好者:(MySQL通過觸發器解決數據庫中表的行數限制詳解及實例)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL通過觸發器解決數據庫中表的行數限制詳解及實例正文
MySQL通過觸發器解決數據庫中表的行數限制詳解及實例
最近項目一個需求是對操作日志的數量限制為10萬條,超過十萬條便刪除最舊的那一條,保存數據庫中日志數量不超過10萬。
當時我的第一想法是通過觸發器來做,便在數據庫中執行了如下的SQL:
delimiter $ create trigger limitLog before insert on OperationLog for each row begin if (select count(*) from OperationLog) > 100000 then delete from OperationLog limit 1; end if; end $ delimiter ;
看起來似乎沒什麼問題,對於insert前執行判斷,如果數量超過100000就執行刪除。但在真正數據庫超過100000條,也就是開始執行IF語句的時候就出問題,MySQL報錯:
ERROR 1442 (HY000): Can't update table 'OperationLog' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
查閱資料才知道,MySQL為了防止觸發器遞歸死循環的執行,不允許在某張表的觸發器中直接對該表進行DML(SELECT,DELETE,UPDATE,INSERT)操作,當然可以對其他表進行這樣操作。
觸發器限制的是執行對該表的DML操作。觸發器可以在你的執行前後來修改要執行的這一行數據,通過set關鍵字。
delimiter $ create trigger setLog before insert on OperationLog for each row begin set NEW.action = 'test'; end $ delimiter ;
上述語句表示在insert OpetationLog表的之前,更新insert這條數據的action字段值為test,NEW就表示新添加的這條字段,同樣的OLD就表示delete時的字段。而在update的時候NEW以及OLD同時都可以使用。
臨時觸發器
剛剛談到的觸發器(Triggers)是基於某個表所產生的事件觸發的,而臨時觸發器也稱為事件調度器是基於特定時間周期觸發來執行某些任務。MySQL的事件調度器可以精確到每秒鐘執行一個任務,而操作系統的計劃任務(如:Linux下的CRON或Windows下的任務計劃)只能精 確到每分鐘執行一次。對於一些對數據實時性要求比較高的應用(例如:股票、賠率、比分等)就非常適合。
在使用這個功能之前必須確保event_scheduler已開啟,可執行
GLOBAL event_scheduler = 1;
或者
SET GLOBAL event_scheduler = ON;
要查看當前是否已開啟事件調度器,可執行如下SQL:
SHOW VARIABLES LIKE 'event_scheduler';
或
SELECT @@event_scheduler;
或
SHOW PROCESSLIST;
而對於本文一開始提到的問題,使用這種機制則可完美解決:
delimiter $ CREATE EVENT limitLog ON SCHEDULE EVERY 1 SECOND DO IF (select count(*) from OperationLog) > 100000 then delete from OperationLog limit 1;END IF $ delimiter ;
親測有效
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!