内容源自:一篇很棒的 MySQL 触发器学习教程

一、触发器概念

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

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

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

二、简单的Insert触发器

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

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

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

  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;

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

注意:创建触发器和表一样,建议增加判断:DROP TRIGGER IF EXISTS `ins_stu`;

三、判断值后调用触发器

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

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;

这个触发器中,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类型;
        StuCostbyHour:统计学生一小时的消费金额,HourCost为金额总数,按小时统计,TimeJD时间段,1~24,对应每小时,RecordTime为统计时间。
        现在需要设计一个实时更新触发器,当插入消费数据时,按小时统计学生的消费金额,同理,用电量等。

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;

SQL语句中,需要获取插入的时间,然后通过TimeJD时间段和日期RecordTime找到对应的值,然后进行累加即可。如下图所示:

五、触发器尽量避免

问题一:
         大型系统必须得要存储过程和触发器吗? - 知乎
回答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触发器的同学,你可以通过触发器实现一些功能,同时需要注意合理的使用触发器,但这个过程需要你不断的去积累和开发,才能真正理解它的用法和使用场所。

转载于:https://www.cnblogs.com/573734817pc/p/10677509.html

关于mysql触发器和存储过程的理解相关推荐

  1. mysql触发器和存储过程_MySql的存储过程和触发器

    Mysql的存储过程是类似于其它编程语言中的函数的功能,存储过程内部可以使用顺序循环和转移三种基本程序结构,而且整个存储过程可以接受和返回参数. 创建存储过程(procedure)时,因为其内部有以; ...

  2. mysql触发器调用存储过程出错_mysql 触发器中调用存储过程

    想要在MYSQL的触发器中调用存储过程,但是IDE提示: 0A000 Not allowed to return a result set from a trigger 触发器代码如下: DELIMI ...

  3. mysql 触发器 for each row 理解_MySQL触发器中的“ FOR EACH ROW”如何工作?

    实际上," FOR EACH ROW"意味着每个匹配的行都将被更新或删除.换句话说,我们可以说触发器没有应用于每一行,它只是说要为每个受影响的表行执行触发器主体.我们可以通过以下示 ...

  4. mysql 触发器和存储过程组合使用,实现定时触发操作

    mysql可以实现定时触发功能,比如说定于某某时间mysql数据库做什么工作,或每隔多长时间做什么工作. 第二种情况应用还是比较广的,比如说我希望每天检查一下我的数据信息,超过一个月的无用信息清除以腾 ...

  5. mysql 触发器 for each row 理解_“for each row”如何在mysql中的触发器中工作?

    FOR EACH ROW表示每个匹配行的更新或删除. 除非查询中有where条件,否则触发器主体不会遍历整个表数据. 下面演示了一个工作示例: 创建样本表: drop table if exists ...

  6. mysql触发器 存储过程_mysql触发器和存储过程

    Mysql触发器和存储过程 1 / 9Mysql触发器 1.语法:命名规则 CREATE TRIGGER { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ...

  7. mysql 触发器 exit_MYSQL触发器和存储过程.ppt

    数据库技术与应用 第四章 MYSQL触发器与存储过程 本章主要内容 4.1 存储过程和函数 存储程序和函数是事先经过编译并存储在数据库中的一套SQL语句.创建后,客户端不需要再重新发布单独的语句,而是 ...

  8. mysql触发器好用吗_为什么大家都不推荐使用MySQL触发器而用存储过程?

    不止一次在各大论坛,文章中看到大多数人不推荐触发器,统统推荐存储过程.这是为什么呢? 现在的场景是:1000万数据,1万并发的规模.疑问: 我的理解是: 触发器本身就是特殊的存储过程,那么如果业务逻辑 ...

  9. PostgreSQL 优势,MySQL 数据库自身的特性并不十分丰富,触发器和存储过程的支持较弱,Greenplum、AWS 的 Redshift 等都是基于 PostgreSQL 开发的...

    PostgreSQL 优势 2016-10-20 21:36 686人阅读 评论(0) 收藏 举报  分类: MYSQL数据库(5)  PostgreSQL 是一个自由的对象-关系数据库服务器(数据库 ...

最新文章

  1. 大数据笔记2019.5.6
  2. JQuery UI - droppable (转载)
  3. C-指针,二级指针,二维数组作为函数参数使用,C语言链表(详解)
  4. boost::mpi模块非阻塞点对点操作的测试
  5. find命令的xargs参数的使用---Linux学习笔记
  6. C#小游戏—钢铁侠VS太空侵略者
  7. P4383 [八省联考 2018] 林克卡特树(wqs二分、树形dp)
  8. 导出excel 后 页面按钮失效(页面假死)
  9. docker安装postgres
  10. android 图片放大缩小_贴在手机上的显微镜,轻松放大400倍,化身“蚁人”玩转微观世界...
  11. springCloud 微服务框架搭建入门
  12. linux中的变量前加__user,linux中的环境变量,别名,变量传递和函数块
  13. Linux平台下卸载MySQL的方法
  14. 2014.9.20CSS样式表
  15. 魔鬼作坊端游脱机封包辅助制作
  16. C++独立游戏存档模块设计
  17. java 字符串替换
  18. plsql报错:Not logged on
  19. MySQL 性能优化参数分析
  20. 【辅助驾驶】激光数据与图像数据的融合[3]——激光及相机位置投影关系

热门文章

  1. ValueError: The QuerySet value for an exact lookup must be limited to one result using slicing.
  2. 信息学奥赛一本通(C++)在线评测系统——基础(三)数据结构 —— 1339:【例3-4】求后序遍历
  3. 决策树---ID3算法
  4. 【Linux】一步一步学Linux——make命令(259)
  5. mysql alert on delete cascade_如何在mysql中删除级联使用?(How do I use on delete cascade in mysql?)...
  6. gsp计算机管理系的功能,药博士医药企业GSP管理系统功能介绍
  7. 基金指数温度怎么算_成都冬季想装明装暖气片那究竟价格应该怎么算?
  8. 51nod 1272 最大距离 O(nlog(n)) , 快排 , 最大连续子串
  9. mongodb存入mysql_关于mongodb转存MySQL
  10. iOS Hacker Xcode7免登录开发者账号打包ipa