初识触发器
专栏内容:
- postgresql使用入门基础
- 手写数据库toadb
- 并发编程
个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
文章目录
- 初识触发器
- 概述
- 触发器的介绍
- 触发器事件
- 行级触发器
- 语句级触发器
- 触发器作用对象
- 表对象触发器
- 视图对象触发器
- 触发器行为
- 数据的可见性
- 总结
- 结尾
概述
在以前,每次入职新员工,HR就特别忙,要验收入职资料,还要找各负责人开通帐号,还要发好些通知,同时还要在各种类型的表格中填加一行新的内容,丝毫不敢马虎大意。
现在使用了数据库系统之后,这些事情就变得简单多了,只需要验收资料,录入新员工信息,其它就会自动触发,这就用到了触发器这一功能。
和其它商业数据库一样,在postgresql 中也支持触发器这一功能,那么什么是触发器呢,又有什么作用呢?
本节内容就是带大家认识一下触发器,以及触发器的作用。
触发器的介绍
触发器 (trigger) 顾名思义就是自动会触发的一种行为,类似于地雷,碰到了就会炸。
在postgresql 中,触发器以下内容组成:
- 触发器定义的触发事件,在等谁来触发它;
- 触发器作用对象,或者是应用的对象,也就是触发器安装到什么地方了;
- 触发器的行为,也就是事件发生后,触发器如何炸,内部填充的内容又是什么;
下面就这两部分展开来聊一聊。
触发器事件
根据触发器事件类型的不同,分为两大类型,一种是行级事件;另一种是语句级的触发器。
下面来看它们有什么不同。
行级触发器
行级触发器(row-level triggers 或 per-row triggers), 对于每个数据行来说,它的变化行为有insert
新增一行数据,update
修改行数据的值,delete
减少一行数据。
针对行数据的变化事件,都可以使触发器工作,每条变动的数据行都会触发,假如一条SQL语句删除了100行,那么就会触发100次。
当然触发器更加精准,还区分了事件发生前 Before
,与事件发生后 after
触发。
从图中可以看到,触发器是在执行修改的节点前后进行触发,每一行数据都会经过扫描节点,modify节点。
语句级触发器
语句级触发器(statement-level triggers 或 per-statement triggers), 是基于SQL语句事件来触发,也就是说无论每条SQL语句影响的数据行有多少,只触发一次。
当然语句级触发器也分事件发生前 Before
,与事件发生后 after
触发。
从图中可以看到,触发器是在整个SQL计划执行的节点前后进行触发,只经过一次,所以也就会只触发一次。
触发器作用对象
上面介绍了触发器的分类,那么触发器可以定义于那些数据库对象上面呢?
触发器可以作用于数据表(table),视图(view)以及外部表(foreign table), 这里特别提一下,postgresql 的触发器可以作用于视图上,这是非常实用的一点。
表对象触发器
可以附加到表(无论是否分区)和外部表上。
它们可以在INSERT、UPDATE、DELETE操作的before
或after
触发器,并且可以是针对每一行或每个SQL语句触发一次。
对于UPDATE触发器,还可以设置为仅当UPDATE语句的SET子句中提到某些列时才触发。
特别的,命令truncate
将表文件截断,将表清空,只能定义为语句级触发器,因为它的执行发生在文件上,与数据行无关。
视图对象触发器
可以附加到视图上。这些触发器通常是INSTEAD OF
触发器,意味着它们会替代对视图执行的INSERT
、UPDATE
或DELETE
操作。
对于每个需要修改的视图行,都会触发一次INSTEAD OF
触发器,也就是它只能是行级触发器。
触发器的函数负责在视图的基表上进行必要的修改,并(在适当时)返回修改后的行, 以视图中的形式表示。
此外,视图上也可以定义在每个SQL语句的before
或after
触发器,但这些仅在视图上的INSTEAD OF
触发器时才会触发。
触发器行为
当触发器事件发生时(即满足触发条件的操作被执行时),触发器的函数会在适当的时间被调用以处理该事件。
这可能涉及修改数据、执行其他SQL语句、调用其他函数或存储过程等。
在postgresql 中,触发器的行为是一个用户自定义的函数,在事件触发时会自动调用此函数,执行对应函数中定义的行为。
数据的可见性
- 对于语句级触发器
BEFORE
语句级触发器不会看到由该语句所做的任何更改。AFTER
语句级触发器会看到该语句所做的所有更改。
- 行级BEFORE触发器
- 触发器函数中的SQL命令不会看到由该触发器即将进行的更改(例如,即将插入、更新或删除的行),因为这些更改尚未发生。
- 它们会看到在本事务的前面命令处理的行所做的数据更改的效果。由于这些更改事件的顺序通常不可预测(一个影响多行的SQL命令可以以任何顺序访问这些行),因此需要谨慎处理。
- 行级AFTER触发器
- 当行级AFTER触发器被触发时,本事务当前命令及之前命令,所有数据更改都已经完成,并且对这些更改的可见性适用于触发器函数。
INSTEAD OF
事件触发器
- 在本事务中,INSTEAD OF触发器将看到由先前触发的INSTEAD OF触发器所做的数据更改的效果。
- 函数稳定性(Function stability)
- 如果触发器函数是用标准过程语言编写的,并且被声明为
VOLATILE
,那么上述规则适用。 - 如果函数被声明为
STABLE
或IMMUTABLE
,则它不会看到调用命令所做的任何更改。
总结
触发器在数据库中有很多用途,例如数据完整性检查、数据审计、自动更新相关表中的数据、防止无效数据进入数据库等。
它们提供了一种在数据库操作中自动执行特定任务的机制,从而减少了应用程序代码中的冗余和复杂性。
结尾
非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!