MySQL触发器更新和插⼊操作
⼀、触发器概念
触发器(trigger):监视某种情况,并触发某种操作,它是提供给程序员和数据分析员来保证数据完整性的⼀种⽅法,它是与表事件相关的特殊的存储过程,它的执⾏不是由程序调⽤,也不是⼿⼯启动,⽽是由事件来触发,例如当对⼀个表进⾏操作( insert,delete,update)时就会激活它执⾏。
触发器经常⽤于加强数据的完整性约束和业务规则等。 触发器创建语法四要素:
1.监视地点(table)
2.监视事件(insert/update/delete)
3.触发时间(after/before)
4.触发事件(insert/update/delete)
触发器基本语法如下所⽰:
eclipse苹果版
其中:trigger_time是触发器的触发事件,可以为before(在检查约束前触发)或after(在检查约束后触发);trigger_event是触发器的触发事件,包括insert、update和delete,需注意对同⼀个表相同触发时间的相同触发事件,只能定义⼀个触发器;可以使⽤old和new来引⽤触发器中发⽣变化的记录内容。
触发器SQL语法:
[shell]
create trigger triggerName
after/before insert/update/delete on 表名
for each row #这句话在mysql是固定的
begin
sql语句;
end;
[/shell]
推荐⼤家阅读:
同时使⽤Navicat for MySQL创建触发器⽅法如下图所⽰,但是建议使⽤语句操作。
⾸先在Navicat for MySQL到需要建⽴触发器对应的表,右键“设计表”,然后创建触发器。
⼆、简单的Insert触发器
数据库系统的软件包括
假设存在⼀张学⽣表(student),包括学⽣的基本信息,学号(stuid)为主键。
另外存在⼀张成绩表(cj),对应每个学⽣包括⼀个值。其中number表⽰序号为主键,⾃动递增序列。它在插⼊过程中默认⾃增。同时假设成绩表中包括学⽣姓名和学号。
该成绩表⽬前没有值,先需要设计⼀个触发器,当增加新的学⽣时,需要在成绩表中插⼊对应的学⽣信息,⾄于具体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]
创建的触发器如下图所⽰:
然后插⼊数据:
insert student values ('eastmount','111111','6','1991-12-05');
同时插⼊两个数据,触发器正确执⾏了~
注意:创建触发器和表⼀样,建议增加判断:DROP TRIGGER IF EXISTS `ins_stu`;
三、判断值后调⽤触发器
这⾥简单讲述⼏个判断插⼊类型的触发器。
⽐如触发器调⽤,当插⼊时间⼩时为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;
四、Update触发器-实时更新
假设存在⼀个实时插⼊数据的服务器,例如学⽣的消费⾦额或⽤电量等。
StuCost:学⽣的⽤电数据,实时插⼊,Cost为每30秒消费⾦额,RecordTime为每分钟插⼊时间,datetime类型;
firebug下载教程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到对应的值,然后进⾏累加即可。如下图所⽰:
上图左边是实时插⼊数据,右边是触发器更新加和。后⾯会介绍实时事件:
五、触发器尽量避免
下⾯简单参考知乎和CSDN论坛,简单讲解⼏个内容:
问题⼀:
回答1:
我们先要弄清楚⼆个问题:
1.什么是⼤型系统?
2.你讨论的是什么领域的应⽤,可以⼤致分为⼆种:互联⽹、企业内部
接下来给你举⼀些例⼦:
1.SAP、peopleSoft、ERP等企业级别应⽤
⼀般情况下,会使⽤存储过程和触发器,减少开发成本,毕竟其业务逻辑修改频繁,⽽且为通⽤,很多时候会把⼀些业务逻辑编写成存储过程,像会写成包,⽐存储过程更强⼤。
求职个人简历模板下载
另外⼀个原因是服务器的负载是可控,也即系统的访问⼈数⾸先是可控的,没有那么⼤,⽽且这些数据⼜⾮常关键,为此往往使⽤的设备也⽐较好,多⽤存储柜⼦⽀撑。
2.另外⼀类互联⽹⾏业的
⽐如淘宝、知呼、微博等,数据库的压⼒是⾮常⼤的,也往往会最容易成为瓶颈,⽽且多⽤PC服务器⽀撑,⽤户量的增速是不可控的,同时在线访问的⽤户量也是不可控的,为此肯定会把业务逻辑放到其他语⾔的代码层,⽽且可以借助⼀些LVS等类型软硬件做负载均衡,以及平滑增减Web层的服务器,从⽽达到线性的增减⽽⽀持⼤规模的访问。
所以不管你的这个系统是否庞⼤,⾸先要分业务⽀持的对象,系统最可能容易出现瓶颈的地⽅在那?
当然也不是说互联⽹⾏业的应⽤就绝对不⽤存储过程,这个也不对,曾在阿⾥做的迁移系统确实⽤了,因为历史的原因,另外还有⼀些新系统也有⽤,⽐如晚上进⾏定期的数据统计的⼀些操作,不过有量上的控制。存储过程是好东西,要分场景,分业务类型来⽤就可以把握好。
回答2:mysql面试题 知乎
肯定不能⼀⼑切的说能⽤或者不能⽤,不同类型的系统、不同的规模、不同的历史原因都会有不同的解决⽅案。
⼀般情况下,Web应⽤的瓶颈常在DB上,所以会尽可能的减少DB做的事情,把耗时的服务做成Scale Out,这种情况下,肯定不会使⽤存储过程;⽽如果只是⼀般的应⽤,DB没有性能上的问题,在适当的场景下,也可以使⽤存储过程。
⾄于触发器,我是知道有这东西但从来没⽤过。我希望风险可控,遇到问题能够快速的到原因,尽可能不会去使⽤触发器。
回答3:
1.PLSQL可以⼤⼤降低parse/exec 百分⽐;go语言怎么样
2.存储过程可以⾃动完成静态SQL variable bind;
3.存储过程⼤⼤减少了JDBC⽹络传输与交互,速度快;
5.存储过程最⼤问题就是给数据库开发⼯作压⼒太⼤,另外升级时候会⽐较难解耦;
6.触发器不推荐使⽤,触发操作能在业务层解决就在业务层解决,否则很难维护,⽽且容易产⽣死锁。
问题2:
回答1:
1.存储过程和触发器⼆者是有很⼤的联系的,我的⼀般理解就是触发器是⼀个隐藏的存储过程,因为它不需要参数,不需要显⽰调⽤,往往在你不知情的情况下已经做了很多操作。从这个⾓度来说,由于是隐藏的,⽆形中增加了系统的复杂性,⾮DBA⼈员理解起来数据库就会有困难,因为它不执⾏根本感觉不到它的存在。
2.再有,涉及到复杂的逻辑的时候,触发器的嵌套是避免不了的,如果再涉及⼏个存储过程,再加上事务等等,很容易出现死锁现象,再调试的时候也会经常性的从⼀个触发器转到另外⼀个,级联关系的不断追溯,很容易使⼈头⼤。其实,从性能上,触发器并没有提升多少性能,只是从代码上来说,可能在coding的时候很容易实现业务,所以我的观点是:摒弃触发器!触发器的功能基本都可以⽤存储过程来实现。
3.在编码中存储过程显⽰调⽤很容易阅读代码,触发器隐式调⽤容易被忽略。
4.存储过程的致命伤在于移植性,存储过程不能跨库移植,⽐如事先是在mysql数据库的存储过程,考虑性能要移植到oracle上⾯那么所有的存储过程都需要被重写⼀遍。
回答2:
这种东西只有在并发不⾼的项⽬,管理系统中⽤。如果是⾯向⽤户的⾼并发应⽤,都不要使⽤。
触发器和存储过程本⾝难以开发和维护,不能⾼效移植。触发器完全可以⽤事务替代。存储过程可以⽤后端脚本替代。
回答3:
我觉得来⾃两⽅⾯的因素:
1.存储过程需要显式调⽤,意思是阅读源码的时候你能知道存储过程的存在,⽽触发器必须在数据库端才能看到,容易被忽略。
2.Mysql的触发器本⾝不是很好,⽐如after delete⽆法链式反应的问题。
我认为性能上其实还是触发器占优势的,但是基于以上原因不受青睐。
最后希望这篇⽂章对你有所帮助,尤其是学习MySQL触发器的同学,你可以通过触发器实现⼀些功能,同时需要注意合理的使⽤触发器,但这个过程需要你不断的去积累和开发,才能真正理解它的⽤法和使⽤场所。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论