在项目中经常要使用事件来处理一些历史数据,现在对数据库事件进行一个总结
事件简介
事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”。
事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。
事件取代了原先只能由操作系统的计划任务来执行的工作,而且mysql的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。
事件的优缺点
2.1 优点
一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。
2.2 缺点
定时触发,不可以调用。
创建事件
CREATE EVENT 的语法如下:
CREATE EVENT
[IF NOT EXISTS] ------------------------------------------------ *标注1
event_name------------------------------------------------------ *标注2
ON SCHEDULE schedule------------------------------------ *标注3
[ON COMPLETION [NOT] PRESERVE] ------------------ *标注4
[ENABLE | DISABLE] ------------------------------------------ *标注5
[COMMENT 'comment'] --------------------------------------- *标注6
DO sql_statement----------------------------------------------- *标注7
说明:
ON SCHEDULE 计划任务,有两种设定计划任务的方式:
1、AT 时间戳,用来完成单次的计划任务。
2、 EVERY 时间(单位)的数量时间单位[STARTS 时间戳] [ENDS时间戳],用来完成重复的计划任务。
在两种计划任务中,时间戳可以是任意的TIMESTAMP 和DATETIME 数据类型,时间戳需要大于当前时间。在重复的计划任务中,时间(单位)的数量可以是任意非空(Not Null)的整数式,时间单位是关键词:YEAR,MONTH,DAY,HOUR,MINUTE 或者SECOND。
提示: 其他的时间单位也是合法的如:QUARTER,WEEK,YEAR_MONTH,DAY_HOUR,DAY_MINUTE,DAY_SECOND,HOUR_MINUTE,HOUR_SECOND,MINUTE_SECOND,不建议使用这些不标准的时间单位。
标注4: [ON COMPLETION [NOT] PRESERVE]
ON COMPLETION参数表示"当这个事件不会再发生的时候",即当单次计划任务执行完毕后或当重复性的计划任务执行到了ENDS阶段。而PRESERVE的作用是使事件在执行完毕后不会被Drop掉,建议使用该参数,以便于查看EVENT具体信息。
标注5:[ENABLE | DISABLE]
参数Enable和Disable表示设定事件的状态。Enable表示系统将执行这个事件。Disable表示系统不执行该事件。可以用如下命令关闭或开启事件:
1、ALTER EVENT event_name ENABLE/DISABLE
标注6:[COMMENT 'comment']
注释会出现在元数据中,它存储在information_schema表的COMMENT列,最大长度为64个字节。'comment'表示将注释内容放在单引号之间,建议使用注释以表达更全面的信息。
标注 7: DO sql_statement
DO sql_statement字段表示该event需要执行的SQL语句或存储过程。这里的SQL语句可以是复合语句,例如:
BEGIN
CREATE TABLE test1;//创建表(需要测试一下)
DROP TABLE test2;//删除表
CALL proc_test1();//调用存储过程
END
使用BEGIN和END标识符将复合SQL语句按照执行顺序放在之间。当然SQL语句是有限制的,对它的限制跟函数Function和触发器Trigger 中对SQL语句的限制是一样的,如果你在函数Function 和触发器Trigger 中不能使用某些SQL,同样的在EVENT中也不能使用。明确的来说有下面几个:LOCK TABLES、UNLOCK TABLES、CREATE EVENT、ALTER EVENT、LOAD DATA
实例:
1、马上执行事件并调用存储过程
CREATE EVENT if not exists Event_Stat_Daily
on schedule EVERY 1 DAY
on completion preserve
do call cp_Stat_VideoData();
2、定时执行事件并调用存储过程
CREATE EVENT Event_Stat_Daily
ON SCHEDULE EVERY 1 DAY STARTS '2017-03-01 02:00:00'
ON COMPLETION PRESERVE
ENABLE
DO call cp_Stat_VideoData();
3、一些简单的处理并没有需要调用存储过程,则将逻辑处理直接写在事件中
DELIMITER |
CREATE EVENT export_access_control_data
ON SCHEDULE
EVERY 1 DAY
STARTS '2017-09-07 00:00:00'
ON COMPLETION PRESERVE
DO
BEGIN
INSERT INTO `access_control_his` (SELECT * FROM `access_control` wWHERE DATE_SUB(CURTIME(), INTERVAL 1 DAY) >= w.`create_time`);
DELETE FROM `access_control` WHERE DATE_SUB(CURTIME(), INTERVAL 1 DAY) >= `create_time`;
END |
DELIMITER ;
其它:
1、事件创建后但是事件并不执行,这个时候就需要检测事件是否开启: SHOW VARIABLES LIKE 'event_scheduler' ; 如果没有开启则是off 或者 DISABLED如果返回的是off表示当前是关闭状态,如果是on当前已经开启了计划任务。在mysql程序的目录下找到my.ini文件,添加一个项:event_scheduler = 1 保存后重启mysql服务即可,重启服务可以在服务管理里面找到
2、也可以用脚本来实现:开启或关闭选择一个指令即可
开启指令:
SET GLOBAL event_scheduler = ON;
SET @@global.event_scheduler = ON;
SET GLOBAL event_scheduler = 1;
SET @@global.event_scheduler = 1;
关闭指令:
SET GLOBAL event_scheduler = OFF;
SET @@global.event_scheduler = OFF;
SET GLOBAL event_scheduler = 0;
SET @@global.event_scheduler = 0;