触发器心得

我觉得它的好处:

1)数据同步性(增加删除就不用说了,还有主表的用户名字段被修改的时候,第二个表的用户名字段是冗余数据可以被一并修改。总金额与各种支付的总额一致)
2)省事,可以少编程(因为很多地方都是操作同一个表,拥有相同的需求)。编程还容易出错。
3)类似于算法的分摊。把功夫下在平时,等到数据要集中使用的时候,就非常方便和准确了。

视图,存储过程,触发器三者,感觉最有用的是触发器。视图有简化逻辑的好处,存储过程有利于写复杂逻辑,但触发器最有利于自动平衡和计算数据,最有用三者都是建立在数据库端的,因此维护非常方便,不需要改变外部应用程序——good!

其实有意思的是需求,怎么样充分利用触发器的功能?
需求:现在我们要购买10辆法拉利。以前是在两个表里先insert后update,但现在只需要insert了
需求:先购买了10个辆法拉利,然后要把数量更改为5,写出触发器;触发器可以自动平衡最终的数量。
需求:若订单数量超过10的话,就认为是恶意订单,只让其购买10个。

触发器应用场合
  1.当向一张表中添加或删除记录时,需要在相关表中进行同步操作。
  比如,当一个订单产生时,订单所购的商品的库存量相应减少。
  2.当表上某列数据的值与其他表中的数据有联系时。
  比如,当某客户进行欠款消费,可以在生成订单时通过设计触发器判断该客户的累计欠款是否超出了最大限度。
  3.当需要对某张表进行跟踪时。
  比如,当有新订单产生时,需要及时通知相关人员进行处理,此时可以在订单表上设计添加触发器加以实现。

 

在一个表上最多建立6个触发器,即1)before insert型,2)before update型,3)before delete型,4)after insert型,5)after update型,6)after delete型。
触发器的一个限制是不能同时在一个表上建立2个相同类型的触发器。这个限制的一个来源是触发器程序体的“begin和end之间允许运行多个语句”(摘自mysql使用手册)

另外还有一点需要注意,msyql除了对insert,update,delete基本操作进行定义外,还定义了load data和replace语句,而load data和replace语句也能引起上述6中类型的触发器的触发。Load data语句用于将一个文件装入到一个数据表中,相当与一系列insert操作。replace语句一般来说和insert语句很像,只是在表中有 primary key和unique索引时,如果插入的数据和原来primary key和unique索引一致时,会先删除原来的数据,然后增加一条新数据;也就是说,一条replace sql有时候等价于一条insert sql,有时候等价于一条delete sql加上一条insert sql。即是:
? Insert型触发器:可能通过insert语句,load data语句,replace语句触发;
? Update型触发器:可能通过update语句触发;
? Delete型触发器:可能通过delete语句,replace语句触发;

before update触发器,如果before触发器执行失败(任何语句都有可能),update sql也会执行失败。
after update 触发器,如果update sql语句执行失败,那么触发器不会执行(任何语句都有可能)。
after update 触发器,如果update sql语句执行成功,触发器却失败(任何语句都有可能),那么sql会回滚。
上述实验所使用的mysql引擎是innodb
无论是before部分的触发器还是after类型的触发器,对于innodb引擎,当触发器执行失败时,相应sql也会执行失败,所以数据库同步也会失败。

当一个表既有before类型的触发器,又有after类型的触发器时;当一条sql语句涉及多个表的update时,sql、触发器的执行顺序经过mysql源码包装过,有时比较复杂:
1) 如果before型触发器执行失败,直接goto跳到err2位置,不会执行后续sql语句;
2) 如果sql执行失败,直接goto跳到err位置,不会执行或许的after型触发器;
3) 如过after触发器执行失败,goto到err2位置,恢复执行过的操作,且在事务型的表上做标记。

delimiter //
create trigger InsertUser
before insert on user
for each row
Begin
IF new.type=1 then
insert into user_group(uid,gid) values(new.uid,'578d3369633b47bd9c1fe8bf905cbfb1');
END IF;
delimiter ;

查看触发器语法如下,如果知道触发器所在数据库,以及触发器名称等具体信息:
SHOW TRIGGERS from SF_User like "usermaps%"; //查看SF_User库上名称和usermaps%匹配的触发器
如果不了解触发器的具体的信息,或者需要查看数据库上所有触发器,如下:
SHOW TRIGGERS; //查看所有触发器
Mysql中有一个information_schema.TRIGGERS表,存储所有库中的所有触发器
desc information_schema.TRIGGERS


问题:
触发器与外部语句操作同一个表的时候,不知道行不行?

原文地址:https://www.cnblogs.com/findumars/p/3092054.html