摘 要: 根據(jù)當前數(shù)據(jù)庫應(yīng)用需求和技術(shù)發(fā)展現(xiàn)狀,研究了數(shù)據(jù)庫管理系統(tǒng)" title="管理系統(tǒng)">管理系統(tǒng)觸發(fā)器機制實現(xiàn)的關(guān)鍵技術(shù)問題,,并以GKD-Base" title="GKD-Base">GKD-Base為原型,,在已有的GKD-Base PL/SQL引擎基礎(chǔ)上實現(xiàn)了數(shù)據(jù)庫的觸發(fā)器功能。
關(guān)鍵詞: PL/SQL引擎 Rete網(wǎng)絡(luò) 雙Hash結(jié)構(gòu) 觸發(fā)器
數(shù)據(jù)庫管理系統(tǒng)作為信息系統(tǒng)的核心部件,,在信息化時代所充當?shù)慕巧瞧渌魏诬浖荒芴娲?。當前?shù)據(jù)庫應(yīng)用的一個普遍要求是數(shù)據(jù)庫管理系統(tǒng)能夠在一些數(shù)據(jù)庫相關(guān)事件發(fā)生時觸發(fā)預(yù)先定義的操作,實現(xiàn)信息管理的自動化,因此引進了觸發(fā)器機制,。觸發(fā)器可以增強引用完整性,,加強復(fù)雜業(yè)務(wù)的規(guī)則,或者監(jiān)控數(shù)據(jù)庫的變動,,并執(zhí)行一定的數(shù)據(jù)操作,。
觸發(fā)器機制實現(xiàn)主要涉及觸發(fā)事件的檢測以及觸發(fā)條件的判決等關(guān)鍵技術(shù)問題,以及對觸發(fā)器的編譯存儲和調(diào)用執(zhí)行等具體操作,。
本文以國產(chǎn)數(shù)據(jù)庫管理系統(tǒng)GKD-Base為原型,,在兼容Oracle 規(guī)范的PL/SQL引擎基礎(chǔ)上,提出一套解決方案,,對觸發(fā)器的關(guān)鍵技術(shù)問題進行了探討,,并設(shè)計實現(xiàn)了數(shù)據(jù)庫的觸發(fā)器機制,擴展了數(shù)據(jù)庫管理系統(tǒng)GKD-Base的功能,。
1 GKD-Base PL/SQL 引擎
GKD-BASE數(shù)據(jù)庫是一個具有自主知識產(chǎn)權(quán)的數(shù)據(jù)庫管理系統(tǒng),,具有兼容SQL89標準的SQL引擎,能夠為用戶提供一個統(tǒng)一,、有效的數(shù)據(jù)庫訪問接口(XAPI),,實現(xiàn)對數(shù)據(jù)庫的各種操作。為了融合SQL語言強大的集合數(shù)據(jù)處理能力" title="處理能力">處理能力和第三代語言(3GL)靈活的過程處理能力,,在GKD-Base上已初步實現(xiàn)了兼容Oarcle PL/SQL V.23的PL/SQL引擎。
GKD-Base PL/SQL引擎包括編譯器,、解釋器和異常處理三個模塊,。在編譯階段,根據(jù)PL/SQL語言兼有過程式語句和SQL語句的特點,,采取分而治之策略,,把過程語句和SQL語句分開處理。對于SQL語句,,編譯器首先建立SQL語句結(jié)點,,進行相應(yīng)的變量綁定和語法檢查;檢查無誤后產(chǎn)生語法樹形式的中間代碼,。對于過程語句,,編譯器將對語句成分進行語法分析,對聲明的變量和數(shù)據(jù)類型建立相應(yīng)的符號表,,最終產(chǎn)生語法樹形式的中間代碼,。解釋器的作用是對編譯器生成的中間代碼進行解釋執(zhí)行。解釋器與編譯器對應(yīng),,具有相對獨立的SQL語句解釋模塊和過程語句解釋模塊,。另外,解釋器還包括執(zhí)行狀態(tài)堆棧的管理、與GKD-Base SQL引擎的調(diào)用接口,。異常處理模塊主要實現(xiàn)程序運行時的錯誤檢查和報告,,并支持用戶自定義異常和預(yù)定義異常的檢查和處理。
GKD-Base PL/SQL引擎可以實現(xiàn)對過程式語句,、SQL語句與游標,、存儲子程序及包的編譯和解釋執(zhí)行。
2 觸發(fā)器實現(xiàn)的關(guān)鍵問題
觸發(fā)器定義了當某些數(shù)據(jù)庫相關(guān)事件發(fā)生時數(shù)據(jù)庫應(yīng)采取的動作,。觸發(fā)器可增強引用完整性,,加強復(fù)雜業(yè)務(wù)的規(guī)則,或者監(jiān)控數(shù)據(jù)庫的變動,,其實現(xiàn)主要涉及到觸發(fā)事件的檢測以及觸發(fā)條件的判決等關(guān)鍵技術(shù)問題,。
2.1 觸發(fā)器的事件檢測機制
觸發(fā)器事件檢測機制包括對事件的檢測和存儲,是實現(xiàn)觸發(fā)器的關(guān)鍵,。觸發(fā)器檢測的事件類型比較簡單,,基本事件主要包括對數(shù)據(jù)的插入、刪除以及更新等,。GKD-Base的觸發(fā)器在對事件檢測時,,直接在相關(guān)事件發(fā)生的前后調(diào)用檢測函數(shù)截獲并分析事件消息,以確定是否對觸發(fā)器點火,。
觸發(fā)器事件檢測機制實現(xiàn)的關(guān)鍵在于對觸發(fā)事件的存儲,。觸發(fā)事件具有時間順序,因此存儲時也必須按照嚴格的時間順序進行存儲,。綜合比較各個商用和實驗數(shù)據(jù)庫系統(tǒng)的事件表存儲機制,,選擇了Starburst的雙" title="的雙">的雙HASH鏈表存儲機制,如圖1,。
這里,,變遷表分為兩種類型:NEW和OLD,分別對應(yīng)于觸發(fā)器行級別操作中的NEW值和OLD值,。變遷表中存儲了事件類型,、當前數(shù)據(jù)表以及事件作用的元組。系統(tǒng)可以通過這個駐留內(nèi)存的雙HASH鏈表實現(xiàn)數(shù)據(jù)庫變遷的快速定位和跟蹤處理,。
2.2 觸發(fā)器的條件判決機制
觸發(fā)器的條件判決機制是觸發(fā)器的核心,,根據(jù)SQL99標準的定義,可以將觸發(fā)器分為前觸發(fā),、約束判定和后觸發(fā)三種類型,。這三種類型觸發(fā)器的判決順序策略如圖2。
觸發(fā)器的條件評估是影響觸發(fā)器機制的最關(guān)鍵因素,。在數(shù)據(jù)庫環(huán)境中,,大多數(shù)數(shù)據(jù)修改行為只能影響數(shù)據(jù)庫的一小部分內(nèi)容,,因此沒必要每次都從頭開始評估觸發(fā)器規(guī)則條件,Rete和TREAT網(wǎng)絡(luò)等增量條件評估方法已經(jīng)被證明是觸發(fā)器條件評估(Condition Evaluation)的有效處理手段,。
以Rete網(wǎng)絡(luò)為例(圖3),,它是一個左深度二叉樹,其基本元素包括:
根結(jié)點:根結(jié)點接收插入/刪除(+/-)記號(tokens),,并將其傳遞給每一個后繼結(jié)點,;
t-const結(jié)點:記號到達這些結(jié)點后,將根據(jù)該結(jié)點上的條件謂詞進行判決,,那些通過測試的記號將繼續(xù)傳播下去,,沒有通過測試的記號則被丟棄掉;
α-存儲結(jié)點:通過t-const結(jié)點測試的記號將存儲到這個結(jié)點中,,存儲在α-存儲結(jié)點中的每一個記號都將同時被傳遞給該結(jié)點的后繼結(jié)點,;
AND(連接)結(jié)點:這些結(jié)點有兩個輸入,到達其中任意一個輸入結(jié)點的記號都要通過AND結(jié)點進行測試,,看它是否需要與另外一個輸入進行連接操作,。如果是,則連接兩個輸入的記號對,,將它們合并成一個組合記號后再傳遞給后繼的β-存儲結(jié)點,;
β-存儲結(jié)點:存儲連接結(jié)點的輸出,并將輸出同時傳遞給后繼結(jié)點,;
P-結(jié)點(規(guī)則結(jié)點):+記號到達這里表明應(yīng)該喚醒一個與該記號相關(guān)聯(lián)的規(guī)則實例,;-記號到達這里表明與其中的標簽對象相關(guān)聯(lián)的已經(jīng)進入待執(zhí)行隊列的規(guī)則實例應(yīng)該被刪除。
Rete網(wǎng)絡(luò)只支持兩路連接,,對于一個有多個關(guān)系參與的規(guī)則定義,,不同的連接順序可以得到不同的Rete網(wǎng)絡(luò),根據(jù)數(shù)據(jù)字典信息可以選擇最優(yōu)的執(zhí)行順序,。圖3是對應(yīng)于規(guī)則條件“A.color =“BULE”AND A.x < B.x AND B.x < C.x”的Rete網(wǎng)絡(luò)示意圖。
3 觸發(fā)器實現(xiàn)算法
觸發(fā)器的具體實現(xiàn)可以分為觸發(fā)器創(chuàng)建和調(diào)用,,此外還包括觸發(fā)器的修改,、刪除等操作。其中觸發(fā)器的創(chuàng)建包括觸發(fā)器的編譯與存儲操作,,觸發(fā)器的調(diào)用包括對觸發(fā)器事件的檢測和觸發(fā)器動作的執(zhí)行,。
3.1創(chuàng)建觸發(fā)器
觸發(fā)器的創(chuàng)建包括觸發(fā)器的編譯和存儲。觸發(fā)器的編譯涉及到觸發(fā)器的命名,、觸發(fā)器事件的正確性檢查,、觸發(fā)器引用表的合法性檢查以及觸發(fā)器主體的語法檢查。觸發(fā)器創(chuàng)建之前首先要檢查用戶是否有創(chuàng)建觸發(fā)器的權(quán)限,,以及觸發(fā)器名是否已經(jīng)在存儲觸發(fā)器的數(shù)據(jù)字典中被使用,。觸發(fā)事件部分在觸發(fā)器創(chuàng)建時要進行檢查,,需要檢查的內(nèi)容包括語法檢查、觸發(fā)器引用的表和列是否存在,,以及用戶是否有針對這個表創(chuàng)建觸發(fā)器的權(quán)限,。表和列的存在與否可以先調(diào)用GKD-Base的XAPI函數(shù)分析出DML語句中表和列的信息,然后根據(jù)這些信息檢查數(shù)據(jù)字典,;權(quán)限的檢查也要到數(shù)據(jù)字典中查詢,。觸發(fā)器的語法檢查通過調(diào)用PL/SQL引擎的編譯器實現(xiàn);PL/SQL引擎編譯器對觸發(fā)器過程語句塊進行編譯,,并生成包含觸發(fā)器所有必要信息的語法樹形式的中間代碼,。
保存觸發(fā)器相關(guān)信息的數(shù)據(jù)結(jié)構(gòu)" title="數(shù)據(jù)結(jié)構(gòu)">數(shù)據(jù)結(jié)構(gòu)最終需要保存在數(shù)據(jù)字典中。因為觸發(fā)器使用單獨的命名空間,,可以設(shè)計一個單獨的系統(tǒng)表作為存儲觸發(fā)器的數(shù)據(jù)字典,。數(shù)據(jù)字典應(yīng)該保存觸發(fā)器調(diào)用過程中必須的信息,類似于Oracle sys.trigger$表,。觸發(fā)器主體是一個語句塊,,對它可以當作一個存儲過程來處理,單獨保存在一個系統(tǒng)表中,,通過觸發(fā)器主體的ID號與存儲在USER_TRIGGERS表中的其它觸發(fā)器信息相關(guān)聯(lián),。在觸發(fā)器調(diào)用過程中,根據(jù)觸發(fā)器中的ID來調(diào)用,。
創(chuàng)建觸發(fā)器算法如下:
(1)合法性驗證,。如當前用戶無權(quán)執(zhí)行該操作,或者用戶給出的表不存在,,轉(zhuǎn)(6),;否則轉(zhuǎn)(2)。
(2)存在性檢查,。如當前定義的觸發(fā)器與當前表以往定義的觸發(fā)器重名或同類型,,轉(zhuǎn)(6);否則轉(zhuǎn)(3),。
(3)語法檢查,。調(diào)用PL/SQL引擎編譯器對觸發(fā)器語句進行編譯,如出現(xiàn)語法或語義錯誤,,轉(zhuǎn)(6),;否則轉(zhuǎn)(4)。
(4)將觸發(fā)器信息寫入外存,,然后返回觸發(fā)器標識ID,。
(5)在數(shù)據(jù)庫表結(jié)構(gòu)的系統(tǒng)表中將(4)中所得標識與觸發(fā)器名填入其中,然后將觸發(fā)器定義的表項插入到USER_TRIGGERS相應(yīng)的系統(tǒng)表項中,,轉(zhuǎn)(7),。
(6)釋放所占資源,,報錯退出。
(7)釋放資源,,正常退出,。
3.2 觸發(fā)器的調(diào)用
觸發(fā)器的調(diào)用首先要從外存中讀取觸發(fā)器的信息,并寫入內(nèi)存相應(yīng)的數(shù)據(jù)結(jié)構(gòu)中,。觸發(fā)器的內(nèi)存形式是為了更方便地進行觸發(fā)器約束條件的檢查而設(shè)立的,。為了在觸發(fā)事件發(fā)生時,能立即判斷當前被處理對象是否滿足觸發(fā)約束條件,,通過調(diào)用PL/SQL引擎編譯器將外存中存放觸發(fā)器約束源代碼轉(zhuǎn)換為其內(nèi)存表示,,存放在相應(yīng)觸發(fā)器的內(nèi)存結(jié)構(gòu)中。
在觸發(fā)器被調(diào)用前,,系統(tǒng)將被同一觸發(fā)事件所觸發(fā)的所有活躍的觸發(fā)器組織成四條鏈,,如圖4。
根據(jù)這個數(shù)據(jù)結(jié)構(gòu),,觸發(fā)器調(diào)用算法如下:
(1)將與觸發(fā)事件相關(guān)的觸發(fā)器按類型分別記入SB,、SA、RB和RA四條鏈中,;如沒有某種類型的觸發(fā)器,,則相應(yīng)鏈置空。
(2)如SB不為空,,則轉(zhuǎn)SB鏈觸發(fā)操作算法,。
(3)如RB不為空,則轉(zhuǎn)RB鏈觸發(fā)操作算法,。
(4)對當前數(shù)據(jù)對象進行觸發(fā)事件所規(guī)定的DML操作,。
(5)如RA不為空,則轉(zhuǎn)RA鏈觸發(fā)操作算法,。
(6)判斷觸發(fā)事件所作用的數(shù)據(jù)記錄是否都被處理完畢,,如是,轉(zhuǎn)(7),;否則,,取出下一條記錄作為當前的數(shù)據(jù)對象,轉(zhuǎn)(3),。
(7)如SA不為空,,則轉(zhuǎn)SA鏈觸發(fā)操作算法,。
(8)釋放所占的資源,,結(jié)束觸發(fā)器調(diào)用的處理。
對給定觸發(fā)器鏈操作算法如下:
(1)根據(jù)觸發(fā)器調(diào)用算法檢測,,當前觸發(fā)器鏈不為空,,取鏈首觸發(fā)器,。
(2)將待處理數(shù)據(jù)對象的相關(guān)信息代入觸發(fā)條件判斷,
如果條件為真,,轉(zhuǎn)(3),;否則轉(zhuǎn)(4)。
(3)啟動一個PL/SQL解釋執(zhí)行器,,對當前觸發(fā)器動作鏈中所記錄的動作進行解釋執(zhí)行,。
(4)取鏈中下一個觸發(fā)器為鏈首,判斷是否為空,,如是,,轉(zhuǎn)(5);否則轉(zhuǎn)(1),。
(5)完成當前觸發(fā)器鏈操作,,返回觸發(fā)器調(diào)用算法繼續(xù)。
觸發(fā)器的更新操作是對一個觸發(fā)器進行編譯后,,替換已存在的作用在同一個表上的同名觸發(fā)器,,基本操作與觸發(fā)器的創(chuàng)建是一致的;觸發(fā)器的刪除操作步驟主要是在數(shù)據(jù)字典中對指定的觸發(fā)器進行查詢并刪除,。這里不再詳述,。
參考文獻
1 唐 揚,熊 偉,陳宏盛等. GKD-Base PL/SQL引擎實現(xiàn)關(guān)鍵技術(shù)研究. 電子技術(shù)應(yīng)用, 2004;30(8)
2 Tom Portfolio. PL/SQL User′s Guide and Reference. Release 8.1.6, Oracle Corporation. 1999
3 J.Widom,,S.Finkelstein. Set Oriented Production Rules in Relational Database Systems. In Proc. ACM SIGMOD, 1990
4 Doorenbos, R. B., Matching 100,000 learned rules. In Proceedings of the Eleventh National Conference on Artificial Intelligence, pages 290~296, 1993
5 C.-L. Forgy. Rete: a Fast Algorithm for the Many Pattern/Many Object Pattern Match Problem. Artificial Intelligence, 1982
6 Miranker, D. P. TREAT: A NEW and Efficient Match Algo-rithm for AI Production Systems. Morgan Kaufmann, San Mateo, CA.