MySQL触发器更新和插入操做

1、触发器概念

触发器(trigger):监视某种状况,并触发某种操做,它是提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,例如当对一个表进行操做( insert,delete, update)时就会激活它执行。
触发器常常用于增强数据的完整性约束和业务规则等。 触发器建立语法四要素:
1.监视地点(table)
2.监视事件(insert/update/delete)
3.触发时间(after/before)
4.触发事件(insert/update/delete)
触发器基本语法以下所示:html

其中:trigger_time是触发器的触发事件,能够为before(在检查约束前触发)或after(在检查约束后触发);trigger_event是触发器的触发事件,包括insert、update和delete,需注意对同一个表相同触发时间的相同触发事件,只能定义一个触发器;可使用old和new来引用触发器中发生变化的记录内容。
触发器SQL语法:mysql

[shell]

create trigger triggerName 
after/before insert/update/delete on 表名 
for each row #这句话在mysql是固定的 
begin 
 sql语句; 
end; 

[/shell]

 

推荐你们阅读:mysql之触发器trigger - 郑志伟
同时使用Navicat for MySQL建立触发器方法以下图所示,可是建议使用语句操做。
首先在Navicat for MySQL找到须要创建触发器对应的表,右键“设计表”,而后建立触发器。程序员

 

2、简单的Insert触发器

假设存在一张学生表(student),包括学生的基本信息,学号(stuid)为主键。sql

另外存在一张成绩表(cj),对应每一个学生包括一个值。其中number表示序号为主键,自动递增序列。它在插入过程当中默认自增。同时假设成绩表中包括学生姓名和学号。shell

该成绩表目前没有值,先须要设计一个触发器,当增长新的学生时,须要在成绩表中插入对应的学生信息,至于具体math、chinese、english后面由老师打分更新便可。
那么,如何设计触发器呢?
1.首先它是一个插入Insert触发器,是创建在表student上的;
2.而后是after,插入后的事件;
3.事件内容是插入成绩表,主须要插入学生的学号和姓名,number为自增,而成绩目前不须要。
注意:new表示student中新插入的值。数据库

[shell] 
create trigger ins_stu 
after insert on student for each row 
begin 
 insert into cj ( stu_id, stu_name) 
 values( new.stuid, new.username); 
end; 
[/shell]

建立的触发器以下图所示:segmentfault

  

而后插入数据:
insert student values ('eastmount','111111','6','1991-12-05');
同时插入两个数据,触发器正确执行了~后端

注意:建立触发器和表同样,建议增长判断:DROP TRIGGER IF EXISTS `ins_stu`;服务器

3、判断值后调用触发器

这里简单讲述几个判断插入类型的触发器。
好比触发器调用,当插入时间小时为20时,对数据进行插入:网络

[shell]
DROP TRIGGER IF EXISTS `ins_info`; 
create trigger ins_info 
after insert on nhfxelect for each row 
begin 
 if HOUR(new.RecordTime)='20' then 
 insert into nhfxbyhour (UnitDepName, UnitDepCode, ElectCost, TimeJG, RecordTime) 
 values( '数统学院', '1', new.USERKWH, '20', new.RecordTime); 
 end if; 
end; 

[/shell]

这个触发器中,RecordTime为datetime类型,如"2016-08-28 20:10:00",这时hour()这个值为20才能插入;不然数据不能插入。同时能够date_format(new.RecordTime, '%Y-%m-%d')判断日期为某天或某年某月进行插入。
同时,再如更新触发器,若是设置的值为某个范围,才进行操做或性别为"男"或"女"才进行操做。
基本语法:
if 判断条件 then
sql语句;
end if;

4、Update触发器-实时更新

假设存在一个实时插入数据的服务器,例如学生的消费金额或用电量等。
StuCost:学生的用电数据,实时插入,Cost为每30秒消费金额,RecordTime为每分钟插入时间,datetime类型;
StuCostbyHour:统计学生一小时的消费金额,HourCost为金额总数,按小时统计,TimeJD时间段,1~24,对应每小时,RecordTime为统计时间。
如今须要设计一个实时更新触发器,当插入消费数据时,按小时统计学生的消费金额,同理,用电量等。

[shell]

DROP TRIGGER IF EXISTS `upd_info`; 
create trigger upd_info 
after insert on StuCost for each row 
begin 
 update StuCostbyHour set HourCost = HourCost + new.Cost 
 where (TimeJD = hour(new.RecordTime) + 1) and date_format(new.RecordTime, '%Y-%m-%d') = date_format(RecordTime, '%Y-%m-%d'); 
end; 

[/shell]

SQL语句中,须要获取插入的时间,而后经过TimeJD时间段和日期RecordTime找到对应的值,而后进行累加便可。以下图所示:

  

上图左边是实时插入数据,右边是触发器更新加和。后面会介绍MySQL实时事件:
http://blog.csdn.net/zlp5201/article/details/38309095

5、触发器尽可能避免

下面简单参考知乎和CSDN论坛,简单讲解几个内容:
问题一:
大型系统必须得要存储过程和触发器吗? - 知乎
回答1:    
咱们先要弄清楚二个问题:
1.什么是大型系统?
2.你讨论的是什么领域的应用,能够大体分为二种:互联网、企业内部
接下来给你举一些例子:
1.SAP、peopleSoft、ERP等企业级别应用
通常状况下,会使用存储过程和触发器,减小开发成本,毕竟其业务逻辑修改频繁,并且为通用,不少时候会把一些业务逻辑编写成存储过程,像Oracle会写成包,比存储过程更强大。
另一个缘由是服务器的负载是可控,也即系统的访问人数首先是可控的,没有那么大,并且这些数据又很是关键,为此每每使用的设备也比较好,多用存储柜子支撑数据库
2.另一类互联网行业的
好比淘宝、知呼、微博等,数据库的压力是很是大的,也每每会最容易成为瓶颈,并且多用PC服务器支撑,用户量的增速是不可控的,同时在线访问的用户量也是不可控的,为此确定会把业务逻辑放到其余语言的代码层,并且能够借助一些LVS等类型软硬件作负载均衡,以及平滑增减Web层的服务器,从而达到线性的增减而支持大规模的访问。
因此无论你的这个系统是否庞大,首先要分业务支持的对象,系统最可能容易出现瓶颈的地方在那?
固然也不是说互联网行业的应用就绝对不用存储过程,这个也不对,曾在阿里作的oracle迁移mysql系统确实用了,由于历史的缘由,另外还有一些新系统也有用,好比晚上进行按期的数据统计的一些操做,不过有量上的控制。存储过程是好东西,要分场景,分业务类型来用就能够把握好。

回答2:
确定不能一刀切的说能用或者不能用,不一样类型的系统、不一样的规模、不一样的历史缘由都会有不一样的解决方案。
通常状况下,Web应用的瓶颈常在DB上,因此会尽量的减小DB作的事情,把耗时的服务作成Scale Out,这种状况下,确定不会使用存储过程;而若是只是通常的应用,DB没有性能上的问题,在适当的场景下,也可使用存储过程。
至于触发器,我是知道有这东西但历来没用过。我但愿风险可控,遇到问题可以快速的找到缘由,尽量不会去使用触发器。

回答3:
1.PLSQL能够大大下降parse/exec 百分比;
2.存储过程能够自动完成静态SQL variable bind;
3.存储过程大大减小了JDBC网络传输与交互,速度快;
4.oracle 中存储过程内部commit为异步写,必定程度上减小了等redo日志落地时间;
5.存储过程最大问题就是给数据库开发工做压力太大,另外架构升级时候会比较难解耦;
6.触发器不推荐使用,触发操做能在业务层解决就在业务层解决,不然很难维护,并且容易产生死锁。

问题2:
为何你们都不推荐使用MySQL触发器而用存储过程?- segmentfault
回答1:
1.存储过程和触发器两者是有很大的联系的,个人通常理解就是触发器是一个隐藏的存储过程,由于它不须要参数,不须要显示调用,每每在你不知情的状况下已经作了不少操做。从这个角度来讲,因为是隐藏的,无形中增长了系统的复杂性,非DBA人员理解起来数据库就会有困难,由于它不执行根本感受不到它的存在。
2.再有,涉及到复杂的逻辑的时候,触发器的嵌套是避免不了的,若是再涉及几个存储过程,再加上事务等等,很容易出现死锁现象,再调试的时候也会常常性的从一个触发器转到另一个,级联关系的不断追溯,很容易令人头大。其实,从性能上,触发器并无提高多少性能,只是从代码上来讲,可能在coding的时候很容易实现业务,因此个人观点是:摒弃触发器!触发器的功能基本均可以用存储过程来实现。
3.在编码中存储过程显示调用很容易阅读代码,触发器隐式调用容易被忽略。
4.存储过程的致命伤在于移植性,存储过程不能跨库移植,好比事先是在mysql数据库的存储过程,考虑性能要移植到oracle上面那么全部的存储过程都须要被重写一遍。

回答2:
这种东西只有在并发不高的项目,管理系统中用。若是是面向用户的高并发应用,都不要使用。
触发器和存储过程自己难以开发和维护,不能高效移植。触发器彻底能够用事务替代。存储过程能够用后端脚本替代。

回答3: 我以为来自两方面的因素: 1.存储过程须要显式调用,意思是阅读源码的时候你能知道存储过程的存在,而触发器必须在数据库端才能看到,容易被忽略。 2.Mysql的触发器自己不是很好,好比after delete没法链式反应的问题。 我认为性能上其实仍是触发器占优点的,可是基于以上缘由不受青睐。 最后但愿这篇文章对你有所帮助,尤为是学习MySQL触发器的同窗,你能够经过触发器实现一些功能,同时须要注意合理的使用触发器,但这个过程须要你不断的去积累和开发,才能真正理解它的用法和使用场所。