当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]数据库触发器机制的设计与实现

摘要:根据当前数据库应用需求和技术发展现状,研究了数据库管理系统触发器机制实现的关键技术问题,并以GKD-Base为原型,在已有的GKD-BasePL/SQL引擎基础上实现了数据库的触发器功能。

关键词:PL/SQL引擎 Rete网络 双Hash结构 触发器

数据库管理系统作为信息系统的核心部件,在信息化时代所充当的角色是其它任何软件所不能替代的。当前数据库应用的一个普遍要求是数据库管理系统能够在一些数据库相关事件发生时触发预先定义的操作,实现信息管理的自动化,因此引进了触发器机制。触发器可以增强引用完整性,加强复杂业务的规则,或者监控数据库的变动,并执行一定的数据操作。

触发器机制实现主要涉及触发事件的检测以及触发条件的判决等关键技术问题,以及对触发器的编译存储和调用执行等具体操作。

本文以国产数据库管理系统GKD-Base为原型,在兼容Oracle规范的PL/SQL引擎基础上,提出一套解决方案,对触发器的关键技术问题进行了探讨,并设计实现了数据库的触发器机制,扩展了数据库管理系统GKD-Base的功能。

1GKD-BasePL/SQL引擎

GKD-BASE数据库是一个具有自主知识产权的数据库管理系统,具有兼容SQL89标准的SQL引擎,能够为用户提供一个统一、有效的数据库访问接口(XAPI),实现对数据库的各种操作。为了融合SQL语言强大的集合数据处理能力和第三代语言(3GL)灵活的过程处理能力,在GKD-Base上已初步实现了兼容OarclePL/SQLV.23的PL/SQL引擎。

GKD-BasePL/SQL引擎包括编译器、解释器和异常处理三个模块。在编译阶段,根据PL/SQL语言兼有过程式语句和SQL语句的特点,采取分而治之策略,把过程语句和SQL语句分开处理。对于SQL语句,编译器首先建立SQL语句结点,进行相应的变量绑定和语法检查;检查无误后产生语法树形式的中间代码。对于过程语句,编译器将对语句成分进行语法分析,对声明的变量和数据类型建立相应的符号表,最终产生语法树形式的中间代码。解释器的作用是对编译器生成的中间代码进行解释执行。解释器与编译器对应,具有相对独立的SQL语句解释模块和过程语句解释模块。另外,解释器还包括执行状态堆栈的管理、与GKD-BaseSQL引擎的调用接口。异常处理模块主要实现程序运行时的错误检查和报告,并支持用户自定义异常和预定义异常的检查和处理。

GKD-BasePL/SQL引擎可以实现对过程式语句、SQL语句与游标、存储子程序及包的编译和解释执行。

2触发器实现的关键问题

触发器定义了当某些数据库相关事件发生时数据库应采取的动作。触发器可增强引用完整性,加强复杂业务的规则,或者监控数据库的变动,其实现主要涉及到触发事件的检测以及触发条件的判决等关键技术问题。

2.1触发器的事件检测机制

触发器事件检测机制包括对事件的检测和存储,是实现触发器的关键。触发器检测的事件类型比较简单,基本事件主要包括对数据的插入、删除以及更新等。GKD-Base的触发器在对事件检测时,直接在相关事件发生的前后调用检测函数截获并分析事件消息,以确定是否对触发器点火。

触发器事件检测机制实现的关键在于对触发事件的存储。触发事件具有时间顺序,因此存储时也必须按照严格的时间顺序进行存储。综合比较各个商用和实验数据库系统的事件表存储机制,选择了Starburst的双HASH链表存储机制,如图1。

图1Starburst中变迁表的双Hash结构

这里,变迁表分为两种类型:NEW和OLD,分别对应于触发器行级别操作中的NEW值和OLD值。变迁表中存储了事件类型、当前数据表以及事件作用的元组。系统可以通过这个驻留内存的双HASH链表实现数据库变迁的快速定位和跟踪处理。

2.2触发器的条件判决机制

触发器的条件判决机制是触发器的核心,根据SQL99标准的定义,可以将触发器分为前触发、约束判定和后触发三种类型。这三种类型触发器的判决顺序策略如图2。

图2三种类型触发器的判决顺序策略图

图3Rete网络示意图

触发器的条件评估是影响触发器机制的最关键因素。在数据库环境中,大多数数据修改行为只能影响数据库的一小部分内容,因此没必要每次都从头开始评估触发器规则条件,Rete和TREAT网络等增量条件评估方法已经被证明是触发器条件评估(ConditionEvaluation)的有效处理手段。

以Rete网络为例(图3),它是一个左深度二叉树,其基本元素包括:

根结点:根结点接收插入/删除(+/-)记号(tokens),并将其传递给每一个后继结点;

t-const结点:记号到达这些结点后,将根据该结点上的条件谓词进行判决,那些通过测试的记号将继续传播下去,没有通过测试的记号则被丢弃掉;

α-存储结点:通过t-const结点测试的记号将存储到这个结点中,存储在α-存储结点中的每一个记号都将同时被传递给该结点的后继结点;

AND(连接)结点:这些结点有两个输入,到达其中任意一个输入结点的记号都要通过AND结点进行测试,看它是否需要与另外一个输入进行连接操作。如果是,则连接两个输入的记号对,将它们合并成一个组合记号后再传递给后继的β-存储结点;

β-存储结点:存储连接结点的输出,并将输出同时传递给后继结点;

P-结点(规则结点):+记号到达这里表明应该唤醒一个与该记号相关联的规则实例;-记号到达这里表明与其中的标签对象相关联的已经进入待执行队列的规则实例应该被删除。

Rete网络只支持两路连接,对于一个有多个关系参与的规则定义,不同的连接顺序可以得到不同的Rete网络,根据数据字典信息可以选择最优的执行顺序。图3是对应于规则条件“A.color=“BULE”ANDA.x

3触发器实现算法

触发器的具体实现可以分为触发器创建和调用,此外还包括触发器的修改、删除等操作。其中触发器的创建包括触发器的编译与存储操作,触发器的调用包括对触发器事件的检测和触发器动作的执行。[!--empirenews.page--]

3.1创建触发器

触发器的创建包括触发器的编译和存储。触发器的编译涉及到触发器的命名、触发器事件的正确性检查、触发器引用表的合法性检查以及触发器主体的语法检查。触发器创建之前首先要检查用户是否有创建触发器的权限,以及触发器名是否已经在存储触发器的数据字典中被使用。触发事件部分在触发器创建时要进行检查,需要检查的内容包括语法检查、触发器引用的表和列是否存在,以及用户是否有针对这个表创建触发器的权限。表和列的存在与否可以先调用GKD-Base的XAPI函数分析出DML语句中表和列的信息,然后根据这些信息检查数据字典;权限的检查也要到数据字典中查询。触发器的语法检查通过调用PL/SQL引擎的编译器实现;PL/SQL引擎编译器对触发器过程语句块进行编译,并生成包含触发器所有必要信息的语法树形式的中间代码。

保存触发器相关信息的数据结构最终需要保存在数据字典中。因为触发器使用单独的命名空间,可以设计一个单独的系统表作为存储触发器的数据字典。数据字典应该保存触发器调用过程中必须的信息,类似于Oraclesys.trigger$表。触发器主体是一个语句块,对它可以当作一个存储过程来处理,单独保存在一个系统表中,通过触发器主体的ID号与存储在USER_TRIGGERS表中的其它触发器信息相关联。在触发器调用过程中,根据触发器中的ID来调用。

创建触发器算法如下:

(1)合法性验证。如当前用户无权执行该操作,或者用户给出的表不存在,转(6);否则转(2)。

(2)存在性检查。如当前定义的触发器与当前表以往定义的触发器重名或同类型,转(6);否则转(3)。

(3)语法检查。调用PL/SQL引擎编译器对触发器语句进行编译,如出现语法或语义错误,转(6);否则转(4)。

(4)将触发器信息写入外存,然后返回触发器标识ID。

(5)在数据库表结构的系统表中将(4)中所得标识与触发器名填入其中,然后将触发器定义的表项插入到USER_TRIGGERS相应的系统表项中,转(7)。

(6)释放所占资源,报错退出。

(7)释放资源,正常退出。

3.2触发器的调用

触发器的调用首先要从外存中读取触发器的信息,并写入内存相应的数据结构中。触发器的内存形式是为了更方便地进行触发器约束条件的检查而设立的。为了在触发事件发生时,能立即判断当前被处理对象是否满足触发约束条件,通过调用PL/SQL引擎编译器将外存中存放触发器约束源代码转换为其内存表示,存放在相应触发器的内存结构中。

在触发器被调用前,系统将被同一触发事件所触发的所有活跃的触发器组织成四条链,如图4。

图4触发器链示意图

根据这个数据结构,触发器调用算法如下:

(1)将与触发事件相关的触发器按类型分别记入SB、SA、RB和RA四条链中;如没有某种类型的触发器,则相应链置空。

(2)如SB不为空,则转SB链触发操作算法。

(3)如RB不为空,则转RB链触发操作算法。

(4)对当前数据对象进行触发事件所规定的DML操作。

(5)如RA不为空,则转RA链触发操作算法。

(6)判断触发事件所作用的数据记录是否都被处理完毕,如是,转(7);否则,取出下一条记录作为当前的数据对象,转(3)。

(7)如SA不为空,则转SA链触发操作算法。

(8)释放所占的资源,结束触发器调用的处理。

对给定触发器链操作算法如下:

(1)根据触发器调用算法检测,当前触发器链不为空,取链首触发器。

(2)将待处理数据对象的相关信息代入触发条件判断,如果条件为真,转(3);否则转(4)。

(3)启动一个PL/SQL解释执行器,对当前触发器动作链中所记录的动作进行解释执行。

(4)取链中下一个触发器为链首,判断是否为空,如是,转(5);否则转(1)。

(5)完成当前触发器链操作,返回触发器调用算法继续。

触发器的更新操作是对一个触发器进行编译后,替换已存在的作用在同一个表上的同名触发器,基本操作与触发器的创建是一致的;触发器的删除操作步骤主要是在数据字典中对指定的触发器进行查询并删除。这里不再详述。

参考文献

1唐扬,熊伟,陈宏盛等.GKD-BasePL/SQL引擎实现关键技术研究.电子技术应用,2004;30(8)

2TomPortfolio.PL/SQLUser´sGuideandReference.Release8.1.6,OracleCorporation.1999

3J.Widom,S.Finkelstein.SetOrientedProductionRulesinRelationalDatabaseSystems.In

Proc.ACMSIGMOD,1990

4Doorenbos,R.B.,Matching100,000learnedrules.InPro-ceedingsoftheEleventhNational

ConferenceonArtificialIntelligence,pages290~296,1993

5C.-L.Forgy.Rete:aFastAlgorithmfortheManyPattern/ManyObjectPattern

MatchProblem.ArtificialIntelligence,1982

6Miranker,D.P.TREAT:ANEWandEfficientMatchAlgo-rithmforAIProductionSystems.

MorganKaufmann,SanMateo,CA.

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭