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 ;
亲测有效
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
相关推荐
-
MySQL触发器使用详解
MySQL包含对触发器的支持.触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行. 创建触发器 在MySQL中,创建触发器语法如下: 复制代码 代码如下: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt 其中: trigger_name:标识触发器名称,用户自行指定: trigger_tim
-
mysql触发器(Trigger)简明总结和使用实例
一,什么触发器 1,个人理解触发器,从字面来理解,一触即发的一个器,简称触发器(哈哈,个人理解),举个例子吧,好比天黑了,你开灯了,你看到东西了.你放炮仗,点燃了,一会就炸了.2,官方定义触发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行.触发器经常用于加强数据的完整性约束和业务规则等. 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数
-
Mysql中的触发器简单介绍及使用案例
什么是触发器? 触发器是数据库的一个程序,他是用来监听着数据表的某个行为,一旦数据表的这个行为发生了,马上执行相应的sql语句 触发器的语法结构: create trigger 触发器的名称触发器事件 on 监听的表名 for each row 行为发生后执行的sql语句 触发器事件组成::两部分组成: 触发器事件发生的时间-----是在监听的表的行为 after before 常用的是after 触发器执行的内容:增删改 创建order 表的时候,需要注意,因为order在mysql中是一个关
-
MYSQL设置触发器权限问题的解决方法
本文实例讲述了MYSQL设置触发器权限的方法,针对权限错误的情况非常实用.具体分析如下: mysql导入数据提示没有SUPER Privilege权限处理,如下所示: ERROR 1419 (HY000): You do not have the SUPER Privilege and Binary Logging is Enabled 导入function . trigger 到 MySQL database,报错: You do not have the SUPER privilege an
-
MySQL笔记之触发器的应用
创建触发器 创建只有一个执行语句的触发器 复制代码 代码如下: CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件ON 表名 FOR EACH ROW 执行语句 其中,触发器名参数指要创建的触发器的名字 BEFORE和AFTER参数指定了触发执行的时间,在事件之前或是之后 FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器 复制代码 代码如下: mysql> CREATE TRIGGER trig1 AFTER INSERT -> ON
-
mysql 触发器实现两个表的数据同步
mysql通过触发器实现两个表的同步 目前,在本地测试成功. 假设本地的两个数据库a和b,a下有表table1(id, val) b下有表table2(id, val) 假设希望当table1中数据更新,table2中数据同步更新. 代码: DELIMITER $$ CREATE /*[DEFINER = { user | CURRENT_USER }]*/ TRIGGER `a`.`触发器名` BEFORE UPDATE ON `a`.`table1` FOR EACH ROW BEGIN I
-
用mysql触发器自动更新memcache的实现代码
mysql 5.1支持触发器以及自定义函数接口(UDF)的特性,如果配合libmemcache以及Memcached Functions for MySQL,就能够实现memcache的自动更新.简单记录一下安装测试步骤. 安装步骤 安装memcached,这个步骤很简单,随处可见 安装mysql server 5.1RC,安装办法也很大众,不废话了 编译libmemcached,解压后安装即可./configure; make; make install 编译Memcached Functio
-
MySQL 在触发器里中断记录的插入或更新?
下面是一种实现的方法.思路就是想办法在触发器中利用一个出错的语句来中断代码的执行. mysql> create table t_control(id int primary key); Query OK, 0 rows affected (0.11 sec) mysql> insert into t_control values (1); Query OK, 1 row affected (0.05 sec) mysql> create table t_bluerosehero(id i
-
MySQL通过触发器解决数据库中表的行数限制详解及实例
MySQL通过触发器解决数据库中表的行数限制详解及实例 最近项目一个需求是对操作日志的数量限制为10万条,超过十万条便删除最旧的那一条,保存数据库中日志数量不超过10万. 当时我的第一想法是通过触发器来做,便在数据库中执行了如下的SQL: delimiter $ create trigger limitLog before insert on OperationLog for each row begin if (select count(*) from OperationLog) > 1000
-
对Python 多线程统计所有csv文件的行数方法详解
如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Thread): #用于统计csv文件的行数的线程类 def __init__(self,path): threading.Thread.__init__(self) #父类初始化 self.path=path #路径 self.line=-1 #统计行数 def run(self): reader =
-
MySQL 数据库 source 命令详解及实例
MySQL 数据库 source 命令详解及实例 MySQL 数据库 source 命令,该命令是数据库导入命令.source 命令的用法非常简单,首先你需要进入 MySQL 数据库的命令行管理界面,然后选择需要导入的数据库,执行 source 命令.如下图所示. MySql 数据库 source 命令 mysql> use test Database changed mysql> set names utf8; Query OK, 0 rows affected (0.00 sec) mys
-
mysql数据库单表最大存储依据详解
目录 引言 数据库单表行数最大多大? 索引的结构 页的结构 从页到索引 B+树承载的记录数量 x怎么算 y的计算 行总数计算 行数超一亿就慢了吗? B树承载的记录数量 总结 引言 故事从好多年前说起. 想必大家也听说过数据库单表建议最大2kw条数据这个说法.如果超过了,性能就会下降得比较厉害. 巧了. 我也听说过. 但我不接受它的建议,硬是单表装了1亿条数据. 这时候,我们组里新来的实习生看到了之后,天真无邪的问我:"单表不是建议最大两千万吗?为什么这个表都放了1个亿还不分库分表"?
-
mysql获取group by的总记录行数另类方法
mysql获取group by内部可以获取到某字段的记录分组统计总数,而无法统计出分组的记录数. mysql的SQL_CALC_FOUND_ROWS 使用 获取查询的行数 在很多分页的程序中都这样写: 代码如下 SELECT COUNT(*) from `table` WHERE ......; 查出符合条件的记录总数 代码如下 SELECT * FROM `table` WHERE ...... limit M,N; 查询当页要显示的数据 这样的语句可以改成: 代码如下 SELECT SQL_
-
MySQL数据库分组查询group by语句详解
一:分组函数的语句顺序 1 SELECT ... 2 FROM ... 3 WHERE ... 4 GROUP BY ... 5 HAVING ... 6 ORDER BY ... 二:WHERE和HAVING筛选条件的区别 数据源 位置 关键字 WHERE 原始表 ORDER BY语句之前 WHERE HAVING 分组后的结果集 ORDER BY语句之后 HAVING 三:举例说明 #1.查询每个班学生的最大年龄 SELECT MAX(age),class FROM STU_CLASS GR
-
MySQL数据库如何给表设置约束详解
目录 一.PK(主键约束) 1.什么是主键? 2.怎么设置主键? 二.FK(外键约束) 1.什么是外键 2.怎么设置外键 三.unique(唯一约束) 1.什么是唯一约束? 2.如何设置唯一约束 四.notnull(非空) 五.default(默认值) 六.auto_increment(自增) 一.PK(主键约束) 1.什么是主键? 在了解主键之前,先了解一下什么是关键字 关键字:在表中具有唯一性的字段,比如一个人的身份证号,学号.一个表中可以有多个关键字. 主键也叫主关键字,就是由一个或多个关
-
MySQL数据库完全备份与增量备份详解
目录 定义 完全备份与恢复演示 定义 完全备份就是将数据库中的数据及所有对象全部备份. 由于 MySQL 服务器中的数据文件是基于磁盘的文本文件,所以完全备份就是复制数据库文件,是最简单也是最快速的方式. 但 MySQL 服务器的数据文件在服务器运行期间,总是处于打开状态,为实现真正的完全备份,需要先停止 MySQL 数据库服务器. 为了保障数据的完整性,在停止 MySQL 服务器之前,需要先执行 flush tables 语句将所有数据写入到数据文件中.对于该方法同学们只需了解,因为将生产环境
-
MySQL系列之redo log、undo log和binlog详解
事务的实现 redo log保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能. InnoDB存储引擎体系结构 redo log Write Ahead Log策略 事务提交时,先写重做日志再修改页:当由于发生宕机而导致数据丢失时,就可以通过重做日志来完成数据的恢复. InnoDB首先将重做日志信息先放到重做日志缓存 按一定频率刷新到重做日志文件 重做日志文件: 在默认情况,InnoDB存储引擎的数据目录下会有两个名为ib_logfile1和ib_logfile2的文件.每个In
-
java 查询oracle数据库所有表DatabaseMetaData的用法(详解)
一 . 得到这个对象的实例 Connection con ; con = DriverManager.getConnection(url,userName,password); DatabaseMetaData dbmd = con.getMetaData(); 二. 方法getTables的用法 原型: ResultSet DatabaseMetaData.getTables(String catalog,String schema,String tableName,String []type
随机推荐
- 如何显示随机信息?
- JavaScript操作表单_动力节点Java学院整理
- 解决Linux程序编译链接动态库版本的相关问题
- Angularjs通过指令监听ng-repeat渲染完成后执行脚本的方法
- 修改系统用户名的批处理代码
- Swift让输入框跟随键盘弹起避免输入输入法挡住输入框问题
- JS根据浏览器窗口大小实时动态改变网页文字大小的方法
- ASP.NET中DataTable与DataSet之间的转换示例
- JScript中遍历Request表单参数集合的方法
- centos 6下安装innodb_ruby
- mysql更改引擎(InnoDB,MyISAM)的方法
- php变量与数组相互转换的方法(extract与compact)
- php从数组中随机选择若干不重复元素的方法
- JQuery中serialize() 序列化
- jQuery使用slideUp方法实现控制元素缓慢收起
- Linux的使用
- 打造完美的IE网页木马
- linux配置java环境变量详细过程
- C#键盘鼠标钩子实例
- VC中BASE64编码和解码使用详解