【MySQL进阶】MySQL触发器详解

news2024/12/26 15:06:01
序号系列文章
7【MySQL基础】运算符及相关函数详解
8【MySQL基础】MySQL多表操作详解
9【MySQL进阶】MySQL事务详解
10【MySQL进阶】MySQL视图详解

文章目录

  • 前言
    • 1,触发器
      • 1.1,触发器概述
      • 1.2,触发器使用环境
    • 2,触发器基本操作
      • 2.1,触发器的创建
      • 2.2,触发器的查看
      • 2.3,触发器的触发
      • 2.4,触发器的删除
    • 3,触发器的优缺点
      • 3.1,触发器的优点
      • 3.2,触发器的缺点
  • 结语


前言

大家好,我是小杨!前面我已经为大家介绍了MySQL中的进阶知识->视图,那么今天我们就给大家讲解MySQL中的触发器这部分的相关内容,希望大家能够收获多多!


1,触发器

1.1,触发器概述

MySQL从 5.0.2 版本开始支持触发器。MySQL的触发器和存储过程一样,都是嵌入到MySQL服务器的一段程序。

触发器是由事件来触发某个操作,这些事件包括 INSERT, UPDATE, DELETE 事件。所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句的时候,就相当于事件发生了,就会自动激发触发器执行相应的操作。

当对数据表中的数据执行插入、更新和删除操作,需要自动执行一些数据库逻辑时,可以使用触发器来实现。

也可以简单理解为:触发器可以看作是一种特殊类型的存储过程,它与存储过程的区别在于存储过程中使用时需要调用,而触发器是在预先定义好的事件(如INSERT,DELETE,UPDATE操作)发生时,才会被MySQL自动调用。


1.2,触发器使用环境

在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息和库存信息分别存放在 2 个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时在库存表中添加一条库存记录。

这样一来,我们就必须把这两个关联的操作步骤写到程序里面,而且要用事务包裹起来,确保这两个操作成为一个原子操作,要么全部执行,要么全部不执行。要是遇到特殊情况,可能还需要对数据进行手动维护,这样就很容易忘记其中的一步,导致数据缺失。

这个时候,咱们就可以使用触发器。你可以创建一个触发器,让商品信息数据的插入操作自动触发库存数据的插入操作。这样一来,就不用担心因为忘记添加库存数据而导致的数据缺失的问题了。


2,触发器基本操作

2.1,触发器的创建

在创建触发器时需要指定触发器的操作对象–数据表,且该数据表不能是临时表或视图。触发器的创建语法如下:

CREATE TRIGGER 触发器名称 触发时机 触发事件 ON 表名称 FOR EACH ROW 触发顺序
BEGIN 
	触发器操作的内容
END;

在上述语法中,指定数据库下的触发器名称必须唯一,也就是说不同的数据库下可以含有名称相同的触发器,而同一个数据库下不可以含有名称相同的触发器。ON 表名称 FOR EACH ROW 触发顺序表示指定触发器的操作对象。

触发时机表示数据表在发生变化前后的两种状态,而触发事件表示激活触发器的操作类型,一般为INSERT,UPADTE,DELETE这三种。触发顺序表示指定同一个表中多个触发器的执行顺序,默认情况下按创建顺序激活。

创建触发器的选项具体描述为:

选项可选值描述
触发时机BEFORE在表中数据发生改变前的状态
AFTER在表中数据已经发生改变后的状态
触发事件INSERT插入操作
UPDATE更新操作
DELETE删除操作
触发顺序FPLLOWS新触发器在现有触发器之后激活
PRECEDES新触发器在现有触发器之前激活

对于每张数据表来说,每个触发事件只允许创建一个触发器,因此,一张数据表根据触发时机的不同最多支持6个触发器。

为了更好地理解触发器的创建及使用,现写个日志表来记录数据的插入修改及删除操作。

1,日志表结构准备

create table stu_logs(
  id int(11) not null auto_increment,
  operation varchar(20) not null comment '操作类型, insert/update/delete',
  operate_time datetime not null comment '操作时间',
  operate_id int(11) not null comment '操作的ID',
  operate_params varchar(500) comment '操作参数',
  primary key(`id`)
)engine=innodb default charset=utf8;

image-20230126211858034

2,插入数据触发器

当往student表中每添加一个数据记录之后,插入数据触发器就会自动触发,记录数据添加记录,插入数据触发器创建的基本语法为:

create trigger stu_insert_trigger
	after insert on student for each row
begin
	insert into stu_logs(id,operation,operate_time,operate_id,operate_params) values
    (null,'insert',now(),new.id,
     concat('插入的数据内容为:id=',new.id,',name=',new.name,',score=',new.score,',group_id=',new.group_id));
end;

当运行结果为下图时,就代表着插入数据触发器就创建完成了,后续在插入数据记录时,就会自动触发插入数据触发器。

image-20230126215956364

如果想更直观地知道该插入数据触发器是否创建成功,可以通过SHOW TRIGGERS来进行触发器的查看操作。

image-20230126222923746

3,修改数据触发器

当对student表中每修改一个数据记录之后,修改数据触发器就会自动触发,记录数据修改信息,修改数据触发器创建的基本语法为:

create trigger stu_update_trigger
	after update on student for each row
begin
	insert into stu_logs(id,operation,operate_time,operate_id,operate_params) values
    (null,'update',now(),new.id,
     concat('更新之前的数据:id=',old.id,',name=',old.name,',score=',old.score,',group_id=',old.group_id,
          ' | 更新之后的数据: id=',new.id,',name=',new.name, ',score=',new.score,',group_id=',new.group_id));
end;

当运行结果为下图时,就代表着修改数据触发器也就创建完成了,后续在修改数据记录时,就会自动触发修改数据触发器。

image-20230126221138523

如果想更直观地知道该修改数据触发器是否创建成功,可以通过SHOW TRIGGERS来进行触发器的查看操作。

image-20230126223004083

4,删除数据触发器

当对student表中每删除一个数据记录之后,删除数据触发器就会自动触发,记录数据删除记录,删除数据触发器创建的基本语法为:

create trigger stu_delete_trigger
	after delete on student for each row
begin
	insert into stu_logs(id,operation,operate_time,operate_id,operate_params) values
    (null,'delete',now(),old.id,
     concat('删除的数据内容为:id=',old.id,',name=',old.name,',score=',old.score,',group_id=',old.group_id));
end;

当运行结果为下图时,就代表着删除数据触发器也就创建完成了,后续在删除数据记录时,就会自动触发删除数据触发器。

image-20230126221052843

如果想更直观地知道该删除数据触发器是否创建成功,也可以通过SHOW TRIGGERS来进行触发器的查看操作。

image-20230126223030987


2.2,触发器的查看

若想要查看指定数据库中已经存在的触发器语句,状态等信息,可以通过两种方式来实现。

1,SHOW TRIGGERS语句查看

在 MySQL 中,可以通过 SHOW TRIGGERS 语句来查看触发器的基本信息,语法格式如下:

SHOW TRIGGERS [{FROM|IN}数据库名称][LIKE '匹配模式' | WHERE 条件表达式];

在上述语法中,若没有使用FROM或者IN指定数据库时,SHOW TRIGGERS语句获取的是当前所在的数据库下所有的触发器,WHERE用于指定查看触发器的条件,LIKE子句用于匹配触发器作用的数据表,而非是触发器名称。

为了更好地理解SHOW TRIGGERS的语法使用,示例如下:

SHOW TRIGGERS;

在对触发器进行查看操作,如果没有添加其余的参数,就会打印出当前数据库下所有的触发器,而这个触发器的创建效果只能通过查看操作来查看,不会专门地去创建一个库或表来保存创建的触发器。

image-20230126221511429

2,在triggers表中查看

在 MySQL 中,所有触发器的信息都存在于information_schema数据库的triggers表中,可以通过SELECT语句来查看,基本语法如下:

SELECT * FROM information_schema.triggers WHERE trigger_name= '触发器名';

在上述语法中,'触发器名'用来指定要查看的触发器的名称,需要用单引号引起来。这种方式可以查询到指定的触发器,使用起来更加方便、灵活。

为了更好地理解SELECT 语句的使用,示例如下:

1,不带指定条件的查询

SELECT * FROM information_schema.triggers;

如果直接使用SELECT对information_schema数据库的triggers表进行查询操作,而没有其它的参数,查询到的结果是MySQL中所有的触发器,系统原有的和自己创建的。例如,下图中的用方框括起来的是自己创建的触发器,剩余的两个就是系统自带的触发器。

image-20230126221806452

2,带指定条件的查询

SELECT * FROM information_schema.triggers WHERE trigger_name= 'stu_insert_trigger';

如果在使用SELECT对information_schema数据库的triggers表进行查询操作时,包含指定条件,系统会查询到满足指定条件的触发器。

image-20230126223154123


2.3,触发器的触发

触发器在创建完成后,若要使触发器触发,则需要让触发器指定的数据表这些设置的对应操作。

为了更好地理解触发器的触发效果,现对上面创建的三种触发器进行逐一演示:

1,插入数据触发器的触发

INSERT INTO student VALUES(2,'xiaoyang',88,1);

image-20230126224813110

2,修改数据触发器的触发

UPDATE student SET score = 98 WHERE name = 'xiaoyang';

image-20230126225304342

3,删除数据触发器的触发

DELETE FROM student WHERE name = 'xiaoyang';

image-20230126225505337


2.4,触发器的删除

触发器的删除操作其实也挺简单,使用DROP TRIGGER语句就可以删除 MySQL 中已经定义的触发器。

DROP TRIGGER [IF EXISTS][数据库.]触发器名称;

在上述语法中,使用IF EXISTS可以避免因触发器不存在而导致删除触发器失败,利用数据库.触发器名称的方式可以删除指定数据库中的触发器;若省略数据库.,则表示删除当前数据库下的触发器;若没有选择数据库则系统会发生报错。

为了更好地理解触发器的删除操作,示例如下:

DROP TRIGGER IF EXISTS stu_insert_trigge;

进行触发器删除操作之前的触发器列表中存在3种触发器,分别为插入数据触发器,修改数据触发器,删除数据触发器这三种。

image-20230126230135837

进行插入数据触发器的删除操作之后,触发器列表中只剩下2种触发器,分别为修改数据,删除数据触发器,而插入数据触发器不存在。

image-20230126230343478

进行触发器的删除操作时,要特别注意触发器的删除只能一个一个地进行删除,不能同时删除多个触发器。

注意事项:在删除一个数据表的同时,也会自动删除该数据表上的触发器。另外,触发器不能被更新或者被覆盖,为了修改一个触发器,必须先删除这个触发器,再重新创建。


3,触发器的优缺点

3.1,触发器的优点

1,触发器可以保证数据安全,进行安全检验。

2,触发器可以通过数据库中的相关表实现级联无痕更改操作。

3,触发器可以侦测数据库内的操作,可以帮助我们记录操作日志。

4,触发器可以在操作数据之前,对相应的数据进行合法性检查。

优点说明:

1,利用触发器帮助我们记录操作日志,也就是具体记录什么时间进行了什么操作。这可以帮助我们更好地还原操作时的具体场景,更好地定位到问题原因所在。

2,人为地对数据库中的数据进行操作难免会出现问题,而这些问题可能会造成很严重的问题,而通过触发器的使用可以避免这类问题,触发器可以在实际插入或者更新操作之前,对相应的数据进行合理性检查,若存在错误,及时提示错误,防止错误数据进入系统。


3.2,触发器的缺点

1,触发器的使用会影响数据库的结构,同时增加了维护的复杂程度。

2,触发器的无痕操作会造成数据在程序(如PHP,Java等)层面的不可控。

3,触发器自身的隐蔽性,进而影响到应用程序中错误原因排查的效率。


结语

这就是本期博客的全部内容啦,想必大家已经对MySQL中的触发器的相关内容有了全新地认识和理解吧,如果有什么其他的问题无法自己解决,可以在评论区留言哦!

最后,如果你觉得这篇文章写的还不错的话或者有所收获的话,麻烦小伙伴们动动你们的小手,给个三连呗(点赞👍,评论✍,收藏📖),多多支持一下!各位的支持是我最大的动力,后期不断更新优质的内容来帮助大家,一起进步。那我们下期见!

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/183095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS7 安装单机 Kafka

一、单机安装 1、上传压缩文件到服务器、解压 tar -zxvf kafka_2.13-3.3.2.tgz -C /usr/local #解压到 usr/local目录下 进入解压目录下 更名kafka mv kafka_2.13-3.3.2/ kafka-3.3.2 2、配置环境变量 vim /etc/profile export KAFKA_HOME/usr/local/kafka-3.3.2export PATH$PA…

MySQL学习记录(9)InnoDB存储引擎

文章目录6、InnoDB存储引擎6.1、逻辑存储结构6.2、架构6.2.1、概述6.2.2、内存结构6.2.3、磁盘结构6.2.4、后台线程6.3、事务原理6.3.1、事务基础6.3.2、redo log日志6.3.3、undo log日志6.4、MVCC6.4.1、基本概念6.4.2、记录中隐藏字段6.4.3、undo log日志6.4.4、readview6.4.…

【Pytorch项目实战】之图像分类与识别:手写数字识别(MNIST)、普适物体识别(CIFAR-10)

文章目录图像分类与识别(一)实战:基于CNN的手写数字识别(数据集:MNIST)(二)实战:基于CNN的图像分类(数据集:CIFAR-10)图像分类与识别 …

Lua 函数 - 可变参数

Lua 函数 - 可变参数 参考至菜鸟教程。 Lua函数可以接收可变数目的参数,和C语言类似,在函数参数列表中使用三点...表示函数有可变的参数。 function add(...) local s 0 for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数…

模拟实现C库函数(2)

"烦恼无影踪,丢宇宙~"上一篇的模拟实现了好几个库函数,strlen\strcpy\memcpy\memmove,那么这一篇又会增加几个常用C库函数的模拟实现 memset\itoa\atoi。一、memsetmemset - fill memory with a constant byte#include <string.h>void *memset(void *s, int c,…

机器自动翻译古文拼音 - 十大宋词 - 江城子·乙卯正月二十日夜记梦 苏轼

江城子乙卯正月二十日夜记梦 宋苏轼 十年生死两茫茫&#xff0c;不思量&#xff0c;自难忘。 千里孤坟&#xff0c;无处话凄凉。 纵使相逢应不识&#xff0c;尘满面&#xff0c;鬓如霜。 夜来幽梦忽还乡&#xff0c;小轩窗&#xff0c;正梳妆。 相顾无言&#xff0c;惟有泪千…

uniapp使用及踩坑项目记录

环境准备 下载 HBuilderX 使用命令行创建项目&#xff1a; 一些常识准备 响应式单位rpx 当设计稿宽度为750px的时&#xff0c;1rpx1px。 uniapp中vue文件style不用添加scoped 打包成h5端的时候自动添加上去&#xff0c;打包成 微信小程序端 不需要添加 scoped。 图片的…

SpringDataJpa set()方法自动保存失效

问题描述&#xff1a;springdatajpa支持直接操作对象设置属性进行更新数据库记录的方式&#xff0c;正常情况下&#xff0c;get()得到的对象直接进行set后&#xff0c;即使不进行save操作&#xff0c;也将自动更新数据记录&#xff0c;将改动持久化到数据库中&#xff0c;但这里…

20230126使AIO-3568J开发板在原厂Android11下跑起来

20230126使AIO-3568J开发板在原厂Android11下跑起来 2023/1/26 18:22 1、前提 2、修改dts设备树 3、适配板子的dts 4、&#xff08;修改uboot&#xff09;编译系统烧入固件验证 前提 因源码是直接使用原厂的SDK&#xff0c;没有使用firefly配套的SDK源码&#xff0c;所以手上这…

Linux安装mongodb企业版集群(分片集群)

目录 一、mongodb分片集群三种角色 二、安装 1、准备工作 2、安装 configsvr配置 router配置 shard配置 三、测试 四、整合Springboot 一、mongodb分片集群三种角色 router角色&#xff1a; mongodb的路由&#xff0c;提供入口&#xff0c;使得分片集群对外透明&…

【目标检测论文解读复现NO.27】基于改进YOLOv5的螺纹钢表面缺陷检测

前言此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;…

【工程化之路】Node require 正解

require 实现原理 流程概述 步骤1&#xff1a;尝试执行代码require("./1"). 开始调用方法require.步骤2&#xff1a;此时会得到filename&#xff0c;根据filename 会判断缓存中是否已经加载模块&#xff0c;如果加载完毕直接返回&#xff0c;反之继续执行步骤3&…

python图像处理(laplacian算子)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和之前的prewitt算子、sobel算子不同,laplacian算子更适合检测一些孤立点、短线段的边缘。因此,它对噪声比较敏感,输入的图像一定要做好噪声的处理工作。同时,laplacian算子设计…

Leetcode 03. 无重复字符的最长子串 [C语言]

目录题目思路1代码1结果1思路2代码2结果2该文章只是用于记录考研复试刷题题目 Leetcode 03: 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所…

尚医通-OAuth2-微信登录接口开发(三十一)

目录&#xff1a; &#xff08;1&#xff09;微信登录-OAuth2介绍 &#xff08;2&#xff09;前台用户系统-微信登录-准备工作 &#xff08;3&#xff09;微信登录-生成微信二维码-接口开发 &#xff08;4&#xff09;微信登录-生成验证码-前端整合 &#xff08;5&#xf…

Telerik DevCraft Ultimate R1 2023

Telerik DevCraft Ultimate R1 2023 Kendo UI R1 2023-添加新的Chip和ChipList组件。 KendoReact R1 2023&#xff08;v5.11.0&#xff09;-新的PDFViewer组件允许用户直接在应用程序中查看PDF文档。 Telerik JustLock R1 2023-Visual Studio快速操作菜单现在可以在创建通用…

蓝桥杯重点(C/C++)(随时更新,更新时间:2023.1.29)

点关注不迷路&#xff0c;欢迎推荐给更多人 目录 1 技巧 1.1 取消同步&#xff08;节约时间&#xff0c;甚至能多骗点分&#xff0c;最好每个程序都写上&#xff09; 1.2 万能库&#xff08;可能会耽误编译时间&#xff0c;但是省脑子&#xff09; 1.3 蓝桥杯return 0…

【数据库-通用知识系列-01】数据库规范化设计之范式,让数据库表看起来更专业

我们在设计数据库时考虑的因素包括读取性能&#xff0c;数据一致性&#xff0c;数据冗余度&#xff0c;可扩展性等&#xff0c;好好学习数据库规范化的知识&#xff0c;设计的数据库表看起来才专业。 范式一览 “键”理解&#xff1a; 超键&#xff1a;在关系中能唯一标识元组…

送什么礼物给小学生比较有纪念意义?适合送小学生的小礼物

送给小学生的礼物哪种比较有意义呢&#xff1f;送给学生的礼物&#xff0c;基本上是对学习有所帮助的&#xff0c;但是像送钢笔、练习册这些&#xff0c;有一部分学生是抗拒的&#xff0c;作为大人就是希望对视力、对成长有用的东西&#xff0c;我认为保护视力是现在许多家庭的…

isNotEmpty() 和 isNotBlank() 的区别,字符串判空, StringUtils工具包 StringUtil工具类,isEmpty() 和 isBlank() 的区别

目录1.StringUtils 和 StringUtilStringUtils 的依赖&#xff1a;StringUtils 的用法&#xff1a;StringUtil 工具类2. isNotEmpty() 和 isNotBlank()1.StringUtils 和 StringUtil 注&#xff1a;StringUtils 和 StringUtil 的区别&#xff08;StringUtil为自定义工具类&#…