MySQL触发器

467 阅读3分钟

本文正在参加「技术专题19期 漫谈数据库技术」活动

之前在聊MySQL的约束的时候聊了触发器的概念和知识点,并没有详细的说明,这里来详细聊聊MySQL触发器。

什么是触发器

MySQL从 5.0.2 版本开始支持触发器。触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性,也就是我们之前聊的约束。

个人理解就是,在我们的业务场景下,会有一些不同数据表之间数据关联的关系,一个表发生修改后,另外的一个表也需要跟着修改,比如:用户表更新密码,用户操作日志表需要连带更新。所以触发器应该是当一个表发生修改之后,自动执行的一个功能。

显而易见,触发器在确保数据的合法性和完整性是十分有帮助的,但是还要注意的是:

1、使用触发器实现的业务逻辑在出现问题时很难定位,尤其是涉及多个触发器时,会使后期维护困难。

2、大量使用触发器容易导致代码结构混乱。

3、触发器的隐式调用容易被忽视,很难排查问题,(之前大佬聊起触发器的时候,说就是因为这个原因不用触发器的。)

触发器分类

根据触发器是由于一个表发生修改才执行的的特性,触发器分为三类和两个时间节点:

三类

INSERT 表示插入记录;

UPDATE 表示更新记录;

DELETE 表示删除记录。

时间节点

BEFORE 表示在事件之前触发;

AFTER 表示在事件之后触发。

触发器命令

使用触发器需要指定数据库,在没有选定操作数据库的时候,命令会报错,

这里还是先列出举例的数据库和数据表。

数据库:practice

数据表:

mysql> desc goods;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| goods_name   | varchar(32)  | YES  |     | NULL    |                |
| count        | int(11)      | YES  |     | NULL    |                |
| goods_price  | float        | YES  |     | NULL    |                |
| origin_place | varchar(200) | YES  |     | NULL    |                |
| origin_time  | varchar(20)  | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
mysql> desc goods_log;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| log_time | date         | YES  |     | NULL    |                |
| content  | varchar(100) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

创建触发器

语法:

create trigger 触发器名称 
[after|before]  -- 触发的时间节点
[insert|update|delete] on -- 触发时间 
goods --触发的表 
for each row --针对表的所有行
begin --开始触发后执行的语句块
insert into goods_log(log_time, content) values(now(),"商品已经生成");  --触发器执行语句块
end; --触发器执行语句块结束

查看触发器

show triggers命令也可以使用from和in进行数据库指定,使用like和where进行条件过滤。

show triggers;
show triggers from goods;
show triggers in practice; --这里注意是数据库名称
show triggers from practice like "%%";
show triggers from practice where "%%";

查看指定表的触发器

select * from 表名.triggers;
select * from 表名.triggers where triggers.name = "触发器名称";

返回的数据结构

字段描述
Event触发器类型,INSERT,UPDATE,DELETE
Table设定触发器的表
Statement触发之后执行的语句块
Timing执行的时间节点 AFTERBEFORE
Created触发器被触发的时间
sql_modesql语句执行的模式
Definer指明谁有权限来执行。DEFINER 表示按定义者拥有的权限来执行
character_set_clientINVOKER 表示用调用者的权限来执行。默认情况下,系统指定为DEFINER字符集编码
collation_connection连接编码
Database_Collation数据库编码

删除触发器

drop trigger add_goods_log_trigger;

案例

添加触发器器,当商品被添加,在商品日志表当中添加添加商品的时间。

create trigger add_goods_log_trigger 
after 
insert on 
goods 
for each row 
begin 
    insert into goods_log(log_time, content) values(now(),"商品已经生成"); 
end;

本文正在参加「技术专题19期 漫谈数据库技术」活动