今天介绍的是mysql的触发器,也属于数据库编程的一种,相对存储过程来说,使用起来更加简单,在某些特定的场景下使用触发器,同样可以达到减少应用程序与mysql服务器交互次数从而提升性能的目的; 1.概念: 触发器是一种特殊的存储过程,在定义触发器时会定义触发器的触发条件,使得触发器在满足触发条件时自动执行而不需要人为调用(存储过程需要人为参与)。 触发器操作的是与表有关的数据库对象,比如在insert/update/delete之前(BEFORE)或之后(AFTER),触发并执行触发器中定义的SQL语句集合。 2.特点: (1)增强数据库的安全性 (2)实现数据库操作的日志审计 (3)实现复杂的级联操作 3.触发器类型: 主要的触发器类型有3种:insert,update,delete,分别使用在不同的场景。 insert类型:通常涉及到数据新增的时候,定义这种类型的触发器,表示新增一条数据后,接下来要触发的动作 update类型:通常发生在修改一条数据时,定义这种类型的触发器,可以记录数据修改之前与修改之后的核心字段值 delete类型:通常记录在某一次删除数据时,通过这种类型的触发器,记录某次删除数据时的核心参数 触发器类型与参数对象的对应关系如下所示: 触发器类型 ? ? ? ? ? ? ? ? ? ? ? ? ?NEW和OLD ? INSERT型触发器 ? ? ? ? ?NEW表示将要或者已经新增的数据 UPDATE型触发器 ? ? ? ? ?OLD表示修改之前的数据 ,NEW表示将要或已经修改后的数据 DELETE型触发器 ? ? ? ? ?OLD表示将要或者已经删除的数据 4.触发器使用: (1)创建触发器语法规则: 创建只有一个执行语句的触发器: create trigger 触发器名 before|after 触发事件 on 表名 for each row 执行语句; 创建有多个执行语句的触发器: create trigger 触发器名 before|after 触发事件 on 表名 for each row? begin 执行语句列表 end; (2)查看触发器 show triggers; (3)删除触发器 drop trigger 触发器名; 示例代码如下: mysql> create database if not exists test; Query OK, 1 row affected (0.01 sec) mysql> use test; Database changed mysql> create table if not exists user( ? ? -> uid int primary key auto_increment, ? ? -> username varchar(50) not null, ? ? -> password varchar(50) not null)default charset=utf8; Query OK, 0 rows affected, 1 warning (0.02 sec) mysql> create table if not exists user_logs( ? ? -> id int primary key auto_increment, ? ? -> time timestamp, ? ? -> log_text varchar(100))default charset=utf8; Query OK, 0 rows affected, 1 warning (0.03 sec) mysql> select * from user; Empty set (0.00 sec) mysql> select * from user_logs; Empty set (0.00 sec) mysql> create trigger trig1 after insert on user for each row ? ? -> insert into user_logs values(NULL,now(),'new'); Query OK, 0 rows affected (0.01 sec) mysql> insert into user values(1,'tom','123456'); Query OK, 1 row affected (0.01 sec) mysql> select * from user; +-----+----------+----------+ | uid | username | password | +-----+----------+----------+ | ? 1 | tom ? ? ?| 123456 ? | +-----+----------+----------+ 1 row in set (0.00 sec) mysql> select * from user_logs; +----+---------------------+----------+ | id | time ? ? ? ? ? ? ? ?| log_text | +----+---------------------+----------+ | ?1 | 2022-12-17 16:37:29 | new ? ? ?| +----+---------------------+----------+ 1 row in set (0.00 sec) mysql> create trigger trig2 after update on user for each row ? ? -> insert into user_logs values(NULL,now(),'newupdate'); Query OK, 0 rows affected (0.01 sec) mysql> update user set username='yang' where uid=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 ?Changed: 1 ?Warnings: 0 mysql> select * from user; +-----+----------+----------+ | uid | username | password | +-----+----------+----------+ | ? 1 | yang ? ? | 123456 ? | +-----+----------+----------+ 1 row in set (0.00 sec) mysql> select * from user_logs; +----+---------------------+-----------+ | id | time ? ? ? ? ? ? ? ?| log_text ?| +----+---------------------+-----------+ | ?1 | 2022-12-17 16:37:29 | new ? ? ? | | ?2 | 2022-12-17 16:37:56 | newupdate | +----+---------------------+-----------+ 2 rows in set (0.00 sec) mysql> create trigger trig3 after delete on user for each row ? ? -> insert into user_logs values(NULL,now(),'newdel'); Query OK, 0 rows affected (0.01 sec) mysql> delete from user where uid = 1; Query OK, 1 row affected (0.01 sec) mysql> select * from user; Empty set (0.00 sec) mysql> select * from user_logs; +----+---------------------+-----------+ | id | time ? ? ? ? ? ? ? ?| log_text ?| +----+---------------------+-----------+ | ?1 | 2022-12-17 16:37:29 | new ? ? ? | | ?2 | 2022-12-17 16:37:56 | newupdate | | ?3 | 2022-12-17 16:38:22 | newdel ? ?| +----+---------------------+-----------+ 3 rows in set (0.00 sec) mysql> show triggers; +---------+--------+-------+------------------------------------------------------+--------+------------------------+--------------------------------------------+----------------+----------------------+----------------------+--------------------+ | Trigger | Event ?| Table | Statement ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Timing | Created ? ? ? ? ? ? ? ?| sql_mode ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | Definer ? ? ? ?| character_set_client | collation_connection | Database Collation | +---------+--------+-------+------------------------------------------------------+--------+------------------------+--------------------------------------------+----------------+----------------------+----------------------+--------------------+ | trig1 ? | INSERT | user ?| insert into user_logs values(NULL,now(),'new') ? ? ? | AFTER ?| 2022-12-17 16:37:08.30 | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | root@localhost | gbk ? ? ? ? ? ? ? ? ?| gbk_chinese_ci ? ? ? | utf8mb4_0900_ai_ci | | trig2 ? | UPDATE | user ?| insert into user_logs values(NULL,now(),'newupdate') | AFTER ?| 2022-12-17 16:37:51.42 | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | root@localhost | gbk ? ? ? ? ? ? ? ? ?| gbk_chinese_ci ? ? ? | utf8mb4_0900_ai_ci | | trig3 ? | DELETE | user ?| insert into user_logs values(NULL,now(),'newdel') ? ?| AFTER ?| 2022-12-17 16:38:21.07 | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | root@localhost | gbk ? ? ? ? ? ? ? ? ?| gbk_chinese_ci ? ? ? | utf8mb4_0900_ai_ci | +---------+--------+-------+------------------------------------------------------+--------+------------------------+--------------------------------------------+----------------+----------------------+----------------------+--------------------+ 3 rows in set (0.00 sec) mysql> drop trigger trig1; Query OK, 0 rows affected (0.01 sec) 5.触发器使用注意事项 合理利用触发器可以帮助应用程序减少与数据库的IO次数,一定程度上提升性能,但是触发器也有一些自身的缺点,在使用的时候需要注意以下几点: (1)可读性较差 触发器最大的一个问题就是可读性差,因为触发器存储在数据库中,并且由事件驱动,这就意味着触发器有可能不受应用层的控制 ,这对系统维护是非常有挑战的。 (2)相关数据的变更,可能会导致触发器出错 特别是涉及到数据的表结构变更,都有可能导致触发器出错,进而影响数据操作的正常运行。这些都会由于触发器本身的隐蔽性,影响到应用中错误原因排查的效率。
|