触发器用于在MySQL执行insert、update或delete语句时自动触发其他SQL代码的执行。这篇文章解释了触发器的正确使用。
触发器可以触发其他SQL代码在语句执行之前或之后运行。触发器可以读取触发器语句更改了哪些数据,但是没有返回值。因此,可以使用触发器来加强业务逻辑的约束,而无需在应用程序中编写相应的代码。
从上面的描述可以看出,触发器可以简化应用程序的逻辑并提高性能,因为触发器的使用减少了应用程序和服务器之间的交互次数。同时,触发器有助于自动更新标准化和统计数据。例如,我们可以使用触发器来自动统计交易订单的总金额、数量和平均客户单价。但是,MySQL触发器的应用也非常有限。如果你使用过其他数据库产品的触发器,不要认为MySQL可以实现同样的功能,比如:
每个数据表中的单个事件只能有一个触发器,也就是说,对于像AFTER INSERT这样的事件,同一时间不能有多个触发器。
MySQL只支持行级触发器,即触发器只能以FOR每行而不是整个SQL语句的方式使用,对于大量数据的操作效率很低。MySQL的触发器只能用以下形式编写:
在|AFTER触发事件之前创建触发器触发器名称
每行的表名
开始
执行语句列表;
结束
执行语句列表支持单个或多个语句。以下是多个语句的示例:
分隔符$$
在对每行的t_users执行INSERT操作后,创建触发器user_create_log
开始
声明log_info VARCHAR(40)字符集utf8
声明描述VARCHAR(20)字符集utf8#后来发现汉字编码乱码,就在这里设置字符集。
集合描述=已创建;
SET log _ info=CONCAT(new . user _ name,description);# CONCAT函数可以连接字符串。
插入到日志(log)值(log _ info);
结束$$
分隔符;
触发器可能会导致服务器执行的实际工作无法预测,一个简单的语句可能会导致服务器执行大量不可见的工作。例如,如果触发器更新相关的表,它可能会使受影响的行数加倍。
触发器很难调试,一旦引入触发器,就很难分析性能瓶颈。
触发器可能导致潜在的锁等待和死锁。如果触发器失败,源查询也将失败。如果没有意识到触发器的存在,很难找到这样的笑话。
在大多数限制中,最大的一个是FOR EACH ROW的设计,这有时会使触发器无法维护统计信息和缓存表,因为它可能很慢。使用触发器的主要原因是,与定时同步更新相比,它们可以保持数据的一致性。触发器不能保证原子性。例如,更新MyISAM数据表的触发器在源SQL语句出错后无法回滚。此外,触发因素本身可能只是错误的。如果我们使用AFTER UPDATE来更新另一个基于MyISAM数据表的表。如果触发器有错误导致第二个表的操作失败,则第一个表的操作不会回滚。
InnoDB的触发器相关操作,包括源语句,都在同一个事务中,所以是原子的。但是,如果您使用InnoDB的触发器来检查与另一个表的数据一致性,如果您此时不小心,可能会导致不正确的结果。例如,如果需要使用触发器来模拟外键,可以使用BEFORE INSERT触发器来验证另一个表中是否有相应的记录。但是,如果在触发器读取另一个表的数据时不使用SELECT FOR UPDATE,则并发问题可能会导致错误的结果。虽然触发器有些缺陷,但不代表不能用。相反,触发器本身也是有用的,特别是对于约束、系统维护任务和保持统计数据最新。
您还可以使用触发器来记录数据行中的更改。这样就连数据库离线手工操作(比如修复错误数据)的记录都可以记录下来。但是,需要注意的是,在向其他自增主键表中插入数据时要小心,这将对重复语句的性能造成问题,因为两个相同的重复值的自增值是不同的。
结论:
触发器可以在有限的情况下充分发挥优势,比如统计、数据表变更日志等。但也存在一些缺陷,比如大量数据的更新是逐行触发的,会降低效率。更何况MyISAM引擎不能保证原子性。所以要看应用场景中是否有触发器。
这就是MySQL触发器的使用细节。更多关于MySQL触发器的信息,请关注我们的其他相关文章!