为什么尽量避免使用mysql触发器使用

为什么尽量避免使用触发器&
如果你是使用的SQL SERVER2000,这个问题会更加严重。触发器操作要作为外部事务的一部分,因此instered和deleted两个虚拟表都是写到事务日志中的。因为日志是顺序写入的,所以在把新旧记录写入日志时,会阻止其它事务写入。同时,读取日志时也会因为有其它写入时而被阻塞。这个无疑给并发操作带来很大影响。
SQL SERVER在内部会把触发器作为一个存储过程来对待,除了不能输入参数等限制外。另一个值得考虑的问题是触发器的执行计划问题,它不随过程的重新编译而编译。上次演示过因为错误的缓存导致的错误的执行计划示例,不知道这个算不算作一个问题。
现在SQL SERVER2005的新旧记录不再保存在日志中,而是使用新的行版本技术存储于tempdb中。这带来了一定程度上的并发优势,但是维护这些版本记录同样也需要额外的开销。同时,在这样的版本链列表中寻找记录也一样会有性能损耗。现在2005的update、delete、insert操作都带了output子句,可以使用它来替换触发器的操作。但是output有个限制是不能直接into到有约束的表,如果有约束也可以先把前后记录存入一个临时的地方再做进一步处理。
下面的代码演示了使用output和trigger时,所观察到的情况,两者都会用到tempdb。但是output是在自己独有的空间中存储这些记录的,而trigger则是在一个公用的空间中存储。因此output会更专职于处理某个请求的操作。具体代码如下:
--更新所有在London的供应商的产品体格为原价格的1.5倍
--创建价格变动历史记录表
IF OBJECT_ID("Price_history","U") IS NOT NULL
DROP TABLE Price_history
SELECT 1 AS ProductID,UnitPrice AS OldPrice,UnitPrice AS NewPrice,GETDATE() AS Date
INTO Price_history
FROM dbo.Products
IF OBJECT_ID("trg_Products_u","TR") IS NOT NULL
DROP TRIGGER trg_Products_u;
--sys.dm_tran_version_store用于存储行版本记录所用,此记录在没有被引用的情况下在一分钟内会被清理线程清除
select * from sys.dm_tran_version_store--确保此时没有版本记录存在
--请确保Products表现在没有任何其它更新触发器存在
--更新完成后发现没有记录相应的行版本,
--如果你打开性能计数器跟踪SQLSERVER:TRANSACTIONS对象的free space in tempdb,你会发现它确实也用到了tempdb。
--因为这个更新没有多少记录,看不出结果。你可以换一个Sales.SalesOrderDetail表来试一下。
set UnitPrice=UnitPrice*1.5
output deleted.ProductID,deleted.UnitPrice,inserted.UnitPrice,getdate() into price_history
from dbo.Products p
join dbo.Suppliers s
on p.SupplierID=s.SupplierID
where s.city=N"London"
select * from sys.dm_tran_version_store
--现在我们创建一个更新触发器来完成此功能
IF OBJECT_ID("trg_Products_u","TR") IS NOT NULL
DROP TRIGGER trg_Products_u;
CREATE TRIGGER trg_Products_u ON dbo.Products FOR UPDATE
--如果更新的不是UnitPrice或没有更新直接返回
IF NOT UPDATE(UnitPrice) OR @@ROWCOUNT=0
INSERT INTO price_history
SELECT i.ProductID,d.UnitPrice,i.UnitPrice,getdate()
FROM inserted i
join deleted d
on i.ProductID=d.ProductID
--使用触发器时,完成更新查看版本记录中有6条记录
--因为在"London"的供应商有三个产品,所以新旧记录加起来总共是6条记录
set UnitPrice=UnitPrice*1.5
from dbo.Products p
join dbo.Suppliers s
on p.SupplierID=s.SupplierID
where s.city=N"London"
select * from sys.dm_tran_version_store
DBCC FREEPROCCACHE;--清除过程缓存以观察触发器的缓存计划
--创建显示重新编译的存储过程
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
IF OBJECT_ID("prc_UpdateProductPrice","P") IS NOT NULL
DROP PROC prc_UpdateProductP
CREATE PROCEDURE prc_UpdateProductPrice
WITH RECOMPILE
SET NOCOUNT ON;
set UnitPrice=UnitPrice*1.5
from dbo.Products p
join dbo.Suppliers s
on p.SupplierID=s.SupplierID
where s.city=N"London"
EXEC prc_UpdateProductPrice
--反复执行上述过程后,发现触发器的执行计划不会因为过程的重新编译而被重新编译
--这可能会因为缓存的原因,造成优化器错误的选择了执行计划
--不知道这个结果是喜是忧
SELECT usecounts, cacheobjtype, objtype, text
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
Copyright (C) , All Rights Reserved.
版权所有 闽ICP备号
processed in 0.032 (s). 12 q(s)博主最新文章
博主热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)[数据库] Navicat for 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是固定的
推荐大家阅读:
同时使用Navicat for MySQL创建触发器方法如下图所示,但是建议使用语句操作。
首先在Navicat for MySQL找到需要建立触发器对应的表,右键“设计表”,然后创建触发器。
二、简单的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
insert into cj ( stu_id, stu_name)
values( new.stuid, new.username);
创建的触发器如下图所示:
然后插入数据:
insert student values ('eastmount','111111','6','');
同时插入两个数据,触发器正确执行了~
注意:创建触发器和表一样,建议增加判断:DROP TRIGGER IF EXISTS `ins_stu`;
三、判断值后调用触发器
这里简单讲述几个判断插入类型的触发器。
比如触发器调用,当插入时间小时为20时,对数据进行插入:
DROP TRIGGER IF EXISTS `ins_info`;
create trigger ins_info
after insert on nhfxelect for each row
if HOUR(new.RecordTime)='20' then
insert into nhfxbyhour (UnitDepName, UnitDepCode, ElectCost, TimeJG, RecordTime)
values( '数统学院', '1', new.USERKWH, '20', new.RecordTime);
这个触发器中,RecordTime为datetime类型,如" 20:10:00",这时hour()这个值为20才能插入;否则数据不能插入。同时可以date_format(new.RecordTime, '%Y-%m-%d')判断日期为某天或某年某月进行插入。
同时,再如更新触发器,如果设置的值为某个范围,才进行操作或性别为"男"或"女"才进行操作。
基本语法:
if 判断条件 then
四、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
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');
SQL语句中,需要获取插入的时间,然后通过TimeJD时间段和日期RecordTime找到对应的值,然后进行累加即可。如下图所示:
上图左边是实时插入数据,右边是触发器更新加和。后面会介绍MySQL实时事件:
五、触发器尽量避免
下面简单参考知乎和CSDN论坛,简单讲解几个内容:问题一:
我们先要弄清楚二个问题:
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:
1.存储过程和触发器二者是有很大的联系的,我的一般理解就是触发器是一个隐藏的存储过程,因为它不需要参数,不需要显示调用,往往在你不知情的情况下已经做了很多操作。从这个角度来说,由于是隐藏的,无形中增加了系统的复杂性,非DBA人员理解起来数据库就会有困难,因为它不执行根本感觉不到它的存在。
2.再有,涉及到复杂的逻辑的时候,触发器的嵌套是避免不了的,如果再涉及几个存储过程,再加上事务等等,很容易出现死锁现象,再调试的时候也会经常性的从一个触发器转到另外一个,级联关系的不断追溯,很容易使人头大。其实,从性能上,触发器并没有提升多少性能,只是从代码上来说,可能在coding的时候很容易实现业务,所以我的观点是:摒弃触发器!触发器的功能基本都可以用存储过程来实现。
3.在编码中存储过程显示调用很容易阅读代码,触发器隐式调用容易被忽略。
4.存储过程的致命伤在于移植性,存储过程不能跨库移植,比如事先是在mysql数据库的存储过程,考虑性能要移植到oracle上面那么所有的存储过程都需要被重写一遍。回答2:
这种东西只有在并发不高的项目,管理系统中用。如果是面向用户的高并发应用,都不要使用。
触发器和存储过程本身难以开发和维护,不能高效移植。触发器完全可以用事务替代。存储过程可以用后端脚本替代。回答3:
我觉得来自两方面的因素:
1.存储过程需要显式调用,意思是阅读源码的时候你能知道存储过程的存在,而触发器必须在数据库端才能看到,容易被忽略。
2.Mysql的触发器本身不是很好,比如after delete无法链式反应的问题。
我认为性能上其实还是触发器占优势的,但是基于以上原因不受青睐。
最后希望这篇文章对你有所帮助,尤其是学习MySQL触发器的同学,你可以通过触发器实现一些功能,同时需要注意合理的使用触发器,但这个过程需要你不断的去积累和开发,才能真正理解它的用法和使用场所。
( By:Eastmount现在的位置:
PPT触发器怎么用
有朋友问什么是,从原理上讲其实很简单,微软官方给出的解释是:触发器仅仅是PPT中的一项功能,它可以是一个图片、图形、按钮,甚至可以是一个段落或文本框,单击触发器时它会触发一个操作,该操作可能是声音、电影或动画。而我对PPT触发器的理解为:通过按钮点击控制PPT页面中已设定动画的执行(读起来相当拗口,但应用才是王道)。
传统的方式对于的执行一般为自定义动画中的“单击”,“之后”和“之前”控制PPT动画执行的条件,需要注意的是,这里的“单击”是在页面空白处,单击鼠标执行动画,当页面所有的动画执行完毕后,再次单击进入下一页,也就是说要想观看下一页的内容,必须在当前页所有动画放映完之后。但是,在一些特殊情况下比如一次培训或销售的,我们需要根据时间和现场情况决定是否要演示一些动画,如果不需要,就可以通过的原理,跳过当前动画,直接进入下一页,如下图:
可以PPT触发器案例打开来看|
PPT页面当中有两个按钮,如果不点击,PPT页面当中的动画不会执行,而直接进入下一页。所以如果你是一位光荣的人民教师,PPT触发器就可以很容易帮你做到与学生的互动:如你可以在PPT上为学生创建一组问题和答案,并将答案选项设置为可显示正确或错误答案的触发器。例如,在“”课堂讲解中,你可以邀请学生猜测有关提高水平的信息:
如:如何快速提高PPT制作水平,下面哪些是正确的?
多看大师的
购买专业的PPT书籍
购买专业的
经常光顾网
无论学生单击哪个答案,都会出现文本或图片,如“您猜对了”,或者播放声音,说明错误或正确答案。PPT触发器可帮助您与学生进行双向互动,引发他们进行猜测、使他们感到愉快、激励他们进行思考和学习、总结错误等等。
而对于设置非常简单,和版本的软件设置相同,选择已设置动画的元素,在自定义动画面板里进行如下设置:
附一个PPT触发器的应用例子,各位可以打开试试看。传送门:
如果你想了解更多关于PPT触发器怎么用的问题,你可以去浏览下面这些教程:
PPT教程网创始人,典型的80后,喜爱熬夜,喜欢一人独处, 喜欢各种新鲜事物,热情却维持不了太久。样样都想学一些,学到现在一样都没学好。崇尚自由生活,钱多固然好,钱少够生活也快乐。最拿手的是...吃饭!
关于本文的小编
【上篇】【下篇】
您可能还会对这些文章感兴趣!
给力的PPT教程分享
PPT教程打包下载通道
关于PPT的百科全书!
PPT素材资源宝藏地
PPT制作速成教程通道
PPT最新模板免费下载
PPT教程排行热榜
PPT设计必备软件
国产PPT制作软件中的神器
PPT2010官方免费下载
PPT2007官方免费下载
PPT2003官方免费下载
轻松把PPT转成FLASH工具
PPT转PDF软件免费下载
最好用的PPT压缩软件
PPT模板下载汇总

我要回帖

更多关于 ppt触发器怎么使用 的文章

 

随机推荐