MySQL触发器的使用


Posted in MySQL onMay 24, 2021

触发器可以在执行语句前或执行后触发其他 SQL 代码运行。触发器可以读取触发语句改变了哪些数据,但是没有返回值。因此可以使用触发器加强业务逻辑的约束而不需要在应用程序写对应的代码。

从上述描述可以看到,触发器可以简化应用程序的逻辑并且可以提升性能,这是因为使用触发器减少了应用程序和服务端的交互次数。同时,触发器有助于完成自动更新归一化和统计数据。例如,我们可以使用触发器自动统计交易订单总金额,订单数及平均客单价。 然而,MySQL 的触发器的应用场合也十分有限,如果你使用过其他数据库产品的触发器,不要以为 MySQL 也能实现相同的功能,例如:

  • 每个数据表的单一事件只能有一个触发器,也就是说对于 AFTER INSERT 这样的事件来说,不能同时有超过1个的触发器。
  • MySQL 只支持行级别的触发器,也就是只能按 FOR EACH ROW 这种方式使用触发而不是整个 SQL 语句,这对于大量数据的操作而言会比较低效。MySQL 的触发器只能按下面的形式编写:
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
    执行语句列表;
END

执行语句列表支持单条或多条语句,下面是一个多条语句的示例:

DELIMITER $$
CREATE TRIGGER user_create_log AFTER INSERT ON t_users FOR EACH ROW
BEGIN
DECLARE log_info VARCHAR(40)character set utf8;
DECLARE description VARCHAR(20) character set utf8;#后面发现中文字符编码出现乱码,这里设置字符集
SET description = " is created";
SET log_info = CONCAT(NEW.user_name, description);     #函数CONCAT可以将字符串连接
INSERT INTO logs(log) values(log_info);
END $$

DELIMITER ;
  • 触发器可能导致服务端实际执行的工作不可预测,一个简单的语句可能导致服务端做大量不可见的工作。例如,如果一个触发器更新了 一个相关的表,可能导致受影响的行数加倍。
  • 触发器难以调试,并且一旦引入了触发器,很难分析性能瓶颈。
  • 触发器会导致潜在的锁等待和死锁。如果触发器失败了,源查询也会失败。如果没有意识到触发器的存在,这类玩呢提很难发现。

大多数限制中,最大的限制是 FOR EACH ROW 的设计,这有时候导致触发器没法用于维护统计和缓存表,这是因为这可能很慢。使用触发器的主要理由是相比定时同步更新,触发器可以一致保持数据的一致性。 触发器也没法保证原子性。例如,更新 MyISAM 数据表的触发器在源 SQL 语句出错后,无法回滚。而且,触发器自身也可能都只错误。如果我们使用了 AFTER UPDATE 基于 MyISAM 数据表去更新另一个表。如果触发器有个导致第二张表操作失败的错误,那对于第一张表的操作不会回滚。

InnoDB 的触发器相关的操作,包括源语句都在同一个事务中,因此是满足原子性的。然而,如果使用InnoDB 的触发器去与另一张表校验数据一致性的时候,这个时候如果不小心的话可能导致不正确的结果。例如,假设需要使用触发器模拟外键,可以使用 BEFORE INSERT触发器验证另一张表是否存在对应的记录,但是如果在触发器读取另一张表数据的时候不使用 SELECT FOR UPDATE的话,则由于并发性性问题可能导致错误的结果。 虽然触发器有些缺陷,但是这并不意味着不能用。相反,触发器本身也是有用的,尤其是对于约束,系统维护任务和保持统计数据保持最新。

也可以使用触发器记录数据行的变化。这样即便是离线手动操作数据库的记录(如修复错误数据)也能够被记录下来。但是,需要注意的是对于往其他自增主键表插入数据时要小心,这对于复制性的语句表现会有问题,因为自增值对于两个相同的副本值并不同。

结语:

触发器在有限的场合能够发挥其优势,比如统计数据、数据表变更日志等。但是也会有一些缺陷,比如大数据量的更新由于逐行触发,会降低效率。还有就是,MyISAM 引擎无法保障原子性。因此,要根据应用场景是否要是有触发器。

以上就是MySQL触发器的使用的详细内容,更多关于MySQL触发器的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
MySQL的join buffer原理
Apr 29 MySQL
详解MySQL数据库千万级数据查询和存储
May 18 MySQL
Mysql 如何查询时间段交集
Jun 08 MySQL
MySQL命令无法输入中文问题的解决方式
Aug 30 MySQL
详细聊聊MySQL中慢SQL优化的方向
Aug 30 MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
Oct 16 MySQL
MYSQL 表的全面总结
Nov 11 MySQL
Linux7.6二进制安装Mysql8.0.27详细操作步骤
Nov 27 MySQL
MySQL数据库完全卸载的方法
Mar 03 MySQL
sql注入报错之注入原理实例解析
Jun 10 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
Jul 15 MySQL
MySQL 重命名表的操作方法及注意事项
May 21 #MySQL
Mysql官方性能测试工具mysqlslap的使用简介
May 21 #MySQL
MySQL官方导出工具mysqlpump的使用
May 21 #MySQL
新手必备之MySQL msi版本下载安装图文详细教程
MySQL数据库压缩版本安装与配置详细教程
MySQL 8.0 之不可见列的基本操作
May 20 #MySQL
Mysql Online DDL的使用详解
May 20 #MySQL
You might like
php相当简单的分页类
2008/10/02 PHP
PHP实现上传图片到 zimg 服务器
2016/10/19 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
JS等比例缩小图片尺寸的实例
2013/02/27 Javascript
Javascript和HTML5利用canvas构建Web五子棋游戏实现算法
2013/07/17 Javascript
extjs 分页使用jsp传递数据示例
2014/07/29 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
2014/11/23 Javascript
javascript中window.open在原来的窗口中打开新的窗口(不同名)
2015/11/15 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
JS中使用变量保存arguments对象的方法
2016/06/03 Javascript
bootstrap下拉列表与输入框组结合的样式调整
2016/10/08 Javascript
Bootstrap与Angularjs的模态框实例代码
2017/08/03 Javascript
JS/HTML5游戏常用算法之路径搜索算法 随机迷宫算法详解【普里姆算法】
2018/12/13 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
vue使用lodop打印控件实现浏览器兼容打印的方法
2021/02/07 Vue.js
详解Python中的静态方法与类成员方法
2017/02/28 Python
python自动发邮件库yagmail的示例代码
2018/02/23 Python
python远程邮件控制电脑升级版
2019/05/23 Python
python实现将文件夹内的每张图片批量分割成多张
2019/07/22 Python
Python ellipsis 的用法详解
2020/11/20 Python
django中cookiecutter的使用教程
2020/12/03 Python
python绘图pyecharts+pandas的使用详解
2020/12/13 Python
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
2013/01/09 HTML / CSS
ECCO爱步官方旗舰店:丹麦鞋履品牌
2018/01/02 全球购物
Nisbets爱尔兰:英国最大的厨房和餐饮设备供应商
2019/01/26 全球购物
Looking4Parking美国:全球排名第一的机场停车比较品牌
2019/08/26 全球购物
YSL圣罗兰美妆俄罗斯官网:Yves Saint Lauret RU
2020/09/23 全球购物
化学相关工作求职信
2013/10/02 职场文书
教师求职推荐信范文
2013/11/20 职场文书
大学生军训自我鉴定
2014/02/12 职场文书
2014年安全管理工作总结
2014/12/01 职场文书
销售2014年度工作总结
2014/12/08 职场文书
公司出纳岗位职责
2015/03/31 职场文书
解决jupyter notebook启动后没有token的坑
2021/04/24 Python
SpringBoot全局异常处理方案分享
2022/05/25 Java/Android
CSS 鼠标选中文字后改变背景色的实现代码
2023/05/21 HTML / CSS