蔡朝晖,刘 春
(大庆师范学院 计算机科学与信息技术学院,黑龙江 大庆 163712)
本文中提到的实验管理系统(以下简称为实验系统),是作者在研项目《软件工程专业理论课程实验管理网络化研究与实现》中实验管理系统应用软件的设计开发和实现部分。
在实验系统的设计和实现过程中,应用DML触发器完成了数据参照完整性实现以及自动更新等功能的实现。完成本文的主要目的:研究、分析、总结应用触发器机制的优势及使用注意事项;同时研究分析了数据库系统中触发器机制的潜在应用。
触发器是数据库服务器中发生事件时自动执行的特殊存储过程。它与存储过程经历的过程类似,但不同的是触发器没有接口,不能被显示调用,只有当某一事件发生时由数据库服务自动执行[1],而我们主要用到的正是它自动执行的优势特性。
一般的DBMS,提供的触发器机制基本都包括DML触发器和DDL触发器两种。如果要通过数据操纵语言(DML)事件修改数据,则执行DML触发器。DML事件是指对表或视图的INSERT、UPDATE或DELETE这三种更新操作。我们在实验系统中使用的DML事件触发器,是针对学生实验管理表的INSERT语句、学生实验成绩表的UPDATE语句、系统用户登录表的DELETE语句而设计触发的。
触发器常用于强制业务规则和数据完整性。数据库系统一般提供两种机制来实现业务规则和数据完整性:约束和触发器。完整性约束机制在检测出违反约束条件的操作后,只能做简单的动作;触发器则可以通过用户使用编程的方法实现复杂的业务规则。在触发器的使用中,应当记住的一个原则是,如果能够通过约束实现数据完整性,那么就使用约束实现。如果无法通过约束实现数据完整性,尝试使用存储过程能否实现,让存储过程在确定更新之前先执行检查。只有在这些方法都无法实现数据完整性时才使用触发器。
每个新学期开学时都应导入新的实验用户数据至实验系统中,这些导入的数据主要是本学期上课学生及任课教师的相关数据,这些数据要同时存储到学生实验成绩管理表和系统用户登录表中。
我们希望在DBA将学生数据信息导入至实验成绩管理表中时,同时实现关于学生用户的信息导入至系统用户登录表中。因为每学期参与完成实验的学生必定是系统用户,而学生信息数据相对于教师信息数据的录入工作量至少是几百倍。
学生完成实验后提交的实验总结,由教师用来做为评价学生实验情况的依据,教师打分完成后,学生就不再具有此实验的使用权限,此时的数据我们希望备份至另附的表中存储。
随着每个学期课程的结束,其相关实验对于本年级开课学生来说也结束了,那么在实验管理系统中,学生成绩上报完成后,实验系统中就可以不必直接管理这些学生的相关信息了,同时登录用户中也应及时删除这些学生的信息。
1)级联插入功能触发器
create trigger tri_stu_insert
on 学生表
for insert
begin
insert into 登录表 values(id,name) as select sno,sname from inserted;
end
//代码说明:其中用到的字段名sno、sname分别为学生学号和学生姓名,登录表中学生用户初始密码默认为“000000”。
2)自动备份功能触发器
create trigger tri_stug_update
on 学生成绩表
for update
begin
if exists
(select * from 备份_学生成绩表 where sno=inserted.sno)
update备份_学生成绩表 set grade=inserted.grade
else
insert into 备份_学生成绩表as select * from inserted;
end
//代码说明:备份_学生成绩表为先前创建好的与学生成绩表完全同构的成绩备份表。
//代码说明:update语句分为两步操作:即捕获数据前像的delete语句和捕获数据后像的insert语句。当在定义有触发器的表上执行update语句时,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。
//另注:此触发器的使用权限只授权给教师用户。
3)级联删除功能触发器
create table 学生成绩表
(
sno char(12),
cno char(8),
pno char(10),
pwork varchar(1000),
grade float default 0,
primary key(sno,pno),
foreign key(sno) references student(sno),
foreign key(pno) references pra(pno)
on delete cascade
);
//代码说明:这里在创建学生成绩表时使用了外码约束,同时直接使用了级联删除机制。由于其实质是系统触发器,所以总结在此。
我们在系统中用到的级联删除功能,直接体现了触发器最常用的功能,即实现数据完整性之参照完整性;对于在实验系统中用到的自动备份功能触发器和级联插入功能触发器,我们意在使用它的主动功能,提高数据录入效率。
尽管级联插入触发器执行时系统开销会比较大,但综合考虑触发器执行频率和数据插入操作频率的对比,设计并使用了该触发器;对于自动备份功能触发器,其在每修改一行学生成绩时会备份其所在行至学生成绩表中,在此使用的是触发器的级联修改机制,只需针对是初始修改还是非初始修改设计即可。对于可能在使用级联更新触发器时产生的更新链循环问题,从设计上给予重视是可以避免的。
许多人将代码重构视为软件开发的一个基本组成部分,而应用开发的一个很大部分是与数据库打交道,重构数据库会引入一些新的问题,所以数据库是重构的一个主要问题领域。做为一个具有完整功能的应用软件,实验系统也不例外,所以在此我们也设计了在实验系统的数据库重构时使用触发器。
4.1.1 理论依据
数据库重构是对数据库模式的一个简单变更,在保持其行为语义和信息语义的同时改进它的设计。而数据库模式既包括结构的方面,也包括功能的方面。所以数据库重构在概念上比代码重构更困难,因为代码重构只需要保持行为语义;另外,由于数据库架构所导致的耦合度,数据库重构会变得更加复杂。[4]
尤其是当有多个外部程序与数据库交互时,一些程序可能在你的控制范围之外。这种情况下,数据库重构会需要一个比较长的转换期,在这个期间,不可能依靠一个应用同时更新两个模式中的表(新、旧模式中的同一个表),所以需要一种像触发器这样的机制来保持它们的值同步,以确保不论应用访问哪一个版本的模式,都能访问到一致的数据。在转换期之后,需要删除重构前的旧值(列/表)和触发器,当然,要在足够的测试可以确保安全时,才能删除它们。
4.1.2 重构策略中同步方法对比分析[4]
根据经验,在数据库重构策略中,触发器在绝大多数情况下都是最好的保证新旧模式同步的方法。触发器优于视图或批量同步,具体参见表1所示:
表1 模式同步策略
4.2.1 理论依据
目前,已经有些商用数据库系统加入了主动机制,即能主动地向用户提供服务,通常称其为主动数据库。它是数据库与人工智能技术相结合的产物,它可以根据应用系统的当前状况,主动适时地做出反应,执行某些操作向用户提供相关信息[1]。主动数据库的核心是规则的概念,而这些规则的初级模型就是触发器,当然,主动规则绝不是触发器设计与使用的简单堆砌。
主动规则由事件、条件、动作组成,记为ECA。规则的基本动作方式是,一旦系统检测到相应规则事件发生,就在特定时刻检查规则的条件,若条件满足,则执行相应的动作。[3,6]
4.2.2 实验有效期监控
在实验系统的实验管理功能中,我们要求按每个实验的有效期来设置权限。即当一个实验布置给学生后的一定时间内,要求学生完成实验并提交实验总结,一旦过了这个时间期限,就将此实验的学生用户权限修改为只读(我们这里采用取消学生所做提交操作)。
通常这个功能由DBA来定期手工完成,哪怕他只是调用存储过程。但如果将这个操作交由主动规则来做,情况就不同了:即我们对实验加一个计时器,用来累计实验布置的天数,实验被学生使用时主动规则被触发,如果这个天数离规定期限还有2天,提醒学生,如果达到期限,则执行规则定义的动作——取消学生的上传实验总结操作。
另外,与提醒学生实验有效期一样,也可以设计一个规则用来监控学生实验成绩,即设定一个阀值,如果学生的成绩低于这个阀值,便会向教师发出警示信息。
在数据库触发器机制的基本应用中,触发器的作用通常主要是用于实现数据完整性,触发器比约束更加灵活,可以实现复杂的数据完整性,另外触发器还可以实现审核更改等更多的功能。仅就实现数据完整性方面,应综合考虑功能和性能开销来决定使用何种数据完整性的方法。约束比较简单,开销低,适用于完整性逻辑比较简单的场合。触发器执行速度快,所引用的表和所影响的行的数目决定了触发器的执行时间,触发器的系统开销很大,在使用触发器之前应该首先考虑使用约束。[1]
慎用级联更新触发器机制,要注意其潜伏着的复杂问题,因为过长的更新链可能降低系统速度,更复杂的问题是这个链构成的自身循环。SQL标准禁止触发器循环,即系统会监视整个更新链,如果遇到循环,取消修改并发出警告。尽管如此,设计者仍然需要避免问题发生,因为不管这类循环收敛还是发散,都会消耗大量资源。使用触发器实现数据库重构的模式同步,以及实验有效期的实时监控等应用,为区别于触发器的直接基本应用,本文将它们归结为潜在应用。也因为这些应用的完成相对比较复杂,更多的涉及到数据库架构耦合度、主动规则终止性分析等复杂问题的研究,究其实质,这些问题主要症结也是源于触发器循环的问题。至于更多的触发器潜在应用,比如基于语义分析的查询优化等,希望在接下来的触发器机制应用中有更深入的研究。
[参考文献]
[1] 周志逵,郭贵锁.数据库系统原理[M].北京: 人民邮电出版社, 2008: 148-157, 295-303 , 391-395.
[2] Ramez Elmasri , Shamkant B. Navathe.数据库系统基础:初级篇[M].北京: 清华大学出版社, 2008: 186-187.
[3] Ramez Elmasri , Shamkant B. Navathe.数据库系统基础:高级篇[M].北京: 清华大学出版社, 2008: 145-152.
[4] Scott W. Ambler , Pramod J. Sadalage[M].数据库重构. 北京: 机械工业出版社, 2007: 10-27 , 39-40 .
[5] Gerald V. Post.数据库管理系统[M]. 北京: 机械工业出版社, 2006: 228-232 .
[6] 郝忠孝.主动数据库系统理论基础[M]. 北京: 科学出版社, 2009: 2-18.