[1] 触发器简单介绍
MySQL 触发器trigger
是一种存储程序,它和一个指定的表相关联,当该表中的数据发生变化(增加、更新、删除)时自动执行。 这些修改数据行的操作被称为触发器事件,例如insert
或者load data
等插入数据的语句可以激活插入触发器。
按照 SQL 标准,触发器可以分为行级触发器row-level trigger
和语句级触发器statement-level trigger
。行级触发器对于修改的每一行数据都会激活一次,如果一个语句插入了 100 行数据,将会调用触发器 100 次;语句级触发器针对每个语句激活一次,一个插入 100 行数据的语句只会调用一次触发器。MySQL只支持行级触发器,不支持预语句级触发器。
不同事件可以激活不同类型的触发器。INSERT
事件触发器用于插入数据的操作,包括 INSERT
、LOAD DATA
、REPLACE
语句等;UPDATE
事件触发器用于更新操作,例如UPDATE
语句;DELETE
事件触发器用于删除操作,例如DELETE
和REPLACE
语句等,DROP TABLE
和TRUNCATE TABLE
语句不会激活删除触发器。
另外,MySQL触发器可以在触发事件之前或者之后执行,分别称为BEFORE
触发器和AFTER
触发器。这两种触发时机可以和不同的触发事件进行组合,例如BEFORE INSERT
触发器或者AFTER UPDATE
触发器。
[2] 触发器的优点
记录并审核用户对表中数据的修改操作,实现审计功能;
实现比检查约束更复杂的完整性约束,例如禁止非业务时间的数据操作;
实现某种业务逻辑,例如增加或删除员工时自动更新部门中的人数;
同步实时地复制表中的数据。
[3] 触发器的缺点:
触发器会增加数据库结构的复杂度,而且触发器对应用程序不可见,难以调试;
触发器需要占用更多的数据库服务器资源,尽量使用数据库提供的非空、唯一、检查约束等;
触发器不能接收参数,只能基于当前的触发对象进行操作。
针对特殊场景使用触发器可以带来一定的便利性;但不要过渡依赖触发器,避免造成数据库的性能下降和维护困难。接下来我们介绍触发器的管理操作。
[4] 触发器在生产环境中如何使用?
触发器可以做一些“酷”的事情,但是在真正大规模的生产环境中,它们会导致许多问题:
会导致难以追踪的性能问题。
触发器在数据库中嵌入了相当于应用程序逻辑的内容,应该被视为事实上的应用程序代码,这可能会触发极难追踪的错误。
触发器的一个古老用例是用于各种类型的安全性,比如不允许人们在对雇员表的查询中看到CEO的薪水。然而,这样的“黄金记录”很少见,可以使用模式设计和现有的SQL授权规则来处理。
在非常大的数据世界中:
· 没有触发器。
· 没有视图。
以上是为了让我们在处理性能问题时保持绝对的清晰。
存储过程仅用于数据库实用程序功能,而不是应用程序逻辑。
当触发器的使用是合理的时,使用触发器是非常有效的。例如,它们在审计(保存数据的历史)方面有很好的价值,而不需要对每个表上的每个CRUD命令都有明确的过程代码。
触发器能够在数据更改之前和之后进行控制。这允许进行验证和业务安全检查。由于这种类型的控件,可以在插入数据库之前和之后执行诸如列格式化之类的任务。
只有在真正需要的时候才使用触发器,如果可能的话,选择使用存储过程。
可能这其中的一些原因是:
过去触发器执行的一些功能现在可以用其他方式执行,如更新总计和自动计算列。
在不知道代码存在的情况下,只检查代码看不到触发器在哪里被调用。当看到数据发生变化时,就会看到它们的影响,并且有时很难弄清楚为什么会发生变化,除非知道有一个触发器或更多的设置在表上。
如果在几个表上使用几个数据库控件,如CHECK
、RI
、Triggers
,那么事务详细流程将变得难以理解和维护。需要确切地知道什么时候会发生什么。同样,需要很好的文档。
[5] 触发器和非触发器存储过程之间的差异:
非触发器存储过程类似于必须从代码、调度程序或批处理作业等中显式调用的程序。而触发器是一种特殊类型的存储过程,它作为事件的响应而触发,而不是由用户直接执行。例如,该事件可以是数据列中数据的变化。
触发器有类型。DDL
触发器和DML
触发器(类型:INSTEAD OF
、For
和AFTER
)
非触发器存储过程可以引用任何类型的对象,但是,要引用视图,必须使用INSTEAD OF
触发器。