这里有新鲜出炉的 Mysql 教程,程序狗速度看过来!
MySQL 是一个开放源码的小型关联式数据库管理系统,开发者为瑞典 MySQL AB 公司。MySQL 被广泛地应用在 Internet 上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了 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 ;
亲测有效
来源: http://www.phperz.com/article/17/0502/333706.html