張曉偉
[摘要]數(shù)據(jù)庫系統(tǒng)本質(zhì)上是一個(gè)用計(jì)算機(jī)存儲(chǔ)記錄的系統(tǒng)。作為數(shù)據(jù)庫的一個(gè)分支,內(nèi)存數(shù)據(jù)庫能為實(shí)時(shí)性提供保障。針對(duì)內(nèi)存數(shù)據(jù)庫的二維表、索引數(shù)據(jù)、單,向資源進(jìn)行詳細(xì)的設(shè)計(jì),并實(shí)現(xiàn)內(nèi)存數(shù)據(jù)庫在應(yīng)用過程中的數(shù)據(jù)同步及并發(fā)性應(yīng)用。
[關(guān)鍵詞]內(nèi)存數(shù)據(jù)庫數(shù)據(jù)同步分布式系統(tǒng)
中圖分類號(hào):TP3文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1671—7597(2009)0210016--02
一、引言
內(nèi)存數(shù)據(jù)庫系統(tǒng)是基于電話交換系統(tǒng)的。與傳統(tǒng)的外存數(shù)據(jù)庫相比,內(nèi)存數(shù)據(jù)庫的最大特點(diǎn)是數(shù)據(jù)長期駐留于主存,作為主拷貝,而硬盤上的備份只用于轉(zhuǎn)存與恢復(fù)。所有對(duì)數(shù)據(jù)關(guān)系的檢索全部在內(nèi)存完成,為實(shí)時(shí)性提供最大保障。同樣,由于數(shù)據(jù)長期駐留在內(nèi)存中,數(shù)據(jù)組織方式、索引方式和操作序列化方式也是按照內(nèi)存的特點(diǎn)做優(yōu)化。
作為數(shù)據(jù)庫的一個(gè)分支,內(nèi)存數(shù)據(jù)庫系統(tǒng)也支持當(dāng)前流行的大型數(shù)據(jù)庫系統(tǒng)的一些流行設(shè)計(jì)思想,如數(shù)據(jù)字典(Data Dictionary)、光標(biāo)操作(Cursor)、保持?jǐn)?shù)據(jù)完整性、一致性的觸發(fā)器(Trigger)、虛刪除(softDelete)[1]。又由于內(nèi)存數(shù)據(jù)庫系統(tǒng)通常都是多模塊系統(tǒng),所以相應(yīng)的要求內(nèi)存數(shù)據(jù)庫具有一定的分布式數(shù)據(jù)庫的能力,完成分布式的資源管理。
二、內(nèi)存數(shù)據(jù)庫的設(shè)計(jì)
(一)二維表對(duì)象
一個(gè)二維表是一個(gè)具體的二元關(guān)系。二維表的每一行稱為表的元組(Tuple)或記錄(Record),每一列稱為表的域(Domain)或字段(Field)。二維表中能確定唯一一條記錄的記錄字段集構(gòu)成二維表的關(guān)鍵字(Key),一個(gè)二維表的關(guān)鍵字可能有多個(gè),其中的一個(gè)稱為二維表的主關(guān)鍵字(Primarykey)。通常一個(gè)二維表的特征如表2-1所示:
表2-1中的描述內(nèi)容包含兩部分:對(duì)象屬性和對(duì)象方法。對(duì)象的屬性描述了對(duì)象的基本特征,所有該對(duì)象的實(shí)例均具有這些特征。對(duì)象的方法規(guī)定了操縱對(duì)象實(shí)例的幾個(gè)基本方法,這些方法可能隨著二維表對(duì)象實(shí)例的不同而不同,因此,在設(shè)計(jì)對(duì)象方法時(shí)需要能夠在需要時(shí)重定義對(duì)象的方法,支持對(duì)象方法的重定義是內(nèi)存數(shù)據(jù)庫系統(tǒng)設(shè)計(jì)的一個(gè)重要方面。
而索引對(duì)象和隊(duì)列對(duì)象都是建立在二維表對(duì)象基礎(chǔ)上的。一個(gè)具體的二維表對(duì)象實(shí)例在運(yùn)行之前必須在系統(tǒng)注冊(cè)登記才能被系統(tǒng)識(shí)別。注冊(cè)定義一個(gè)具體的二維表的方法步驟如下,其中[]為可選部分,對(duì)于有些二維表不需要索引或隊(duì)列管理:注冊(cè)一個(gè)空表;在所注冊(cè)的空表中逐個(gè)增加字段;提供為所有二維表對(duì)象預(yù)定義的若干方法;為二維表建立存儲(chǔ)區(qū);[注冊(cè)二維表的索引對(duì)象];[為索引建立存儲(chǔ)區(qū)];[注冊(cè)隊(duì)列對(duì)象]:[為隊(duì)列建立存儲(chǔ)區(qū)]。
(二)索引數(shù)據(jù)在內(nèi)存中的表示
索引定義有兩類:順序索引、HASH索引[2]。對(duì)于順序索引,索引表的每個(gè)索引項(xiàng)由“索引關(guān)鍵字和索引記錄號(hào)”兩部分組成,索引表的索引項(xiàng)按“索引關(guān)鍵字”有序排列,如圖2-1所示,采用二分法檢索。在本系統(tǒng)中主要采用順序索引。
索引是給這些需要經(jīng)常查找的字段維護(hù)一張索引表,索引表中的記錄有字段值(或者是字段值經(jīng)過映射的信息)信息和相應(yīng)記錄的位置(記錄號(hào)),字段值(或者是字段值經(jīng)過映射的信息)作為索引記錄表的關(guān)鍵字。于是查找記錄可以通過先查找索引表獲得記錄號(hào),然后就可以從表中獲得記錄。順序索引原理如圖2-2所示:
(三)表對(duì)象中單向資源隊(duì)列的處理
單向資源隊(duì)列在關(guān)系表中用于維護(hù)二維表數(shù)據(jù)區(qū)中空閑的內(nèi)存塊信息。為此,在二維表對(duì)象中稱其為空閑隊(duì)列。此外,它還作為同步對(duì)象中的失步隊(duì)列用于記錄失步記錄。單向資源隊(duì)列對(duì)象是供表對(duì)象和同步對(duì)象內(nèi)部使用的對(duì)象。單向資源隊(duì)列根據(jù)它在表對(duì)象和同步對(duì)象作用分別又稱為單向資源隊(duì)列對(duì)象和失步記錄隊(duì)列對(duì)象。表對(duì)象管理大量的記錄,這些一記錄是存放在一個(gè)記錄數(shù)組中的,當(dāng)其中某些記錄刪除之后,存放相應(yīng)記錄的內(nèi)存就會(huì)空閑出來,當(dāng)要向表插入記錄時(shí),就需要知道那塊內(nèi)存是空的,如果一個(gè)一個(gè)找顯然降低處理速度,為此就需要維護(hù)一個(gè)單向資源隊(duì)列,記錄空閑內(nèi)存的位置[3]。在表對(duì)象中與單向資源隊(duì)列相關(guān)的操作的關(guān)鍵的有兩個(gè):
1、當(dāng)向表實(shí)例中插入記錄時(shí),首先要?jiǎng)h除單向資源隊(duì)列隊(duì)尾元素,然后獲得空閑內(nèi)存位置,再在該內(nèi)存位置上寫入記錄內(nèi)存。
2、當(dāng)從表實(shí)例刪除記錄之后,要將給內(nèi)存位置信息插入該單向資源隊(duì)列,以使該隊(duì)列記錄空閑內(nèi)存位置。
此外,在表創(chuàng)建一個(gè)空閑對(duì)象實(shí)例并初始化該隊(duì)列和在表實(shí)例撤銷時(shí),同時(shí)撤銷該隊(duì)列也是不可缺少的。
三、內(nèi)存數(shù)據(jù)庫的應(yīng)用
(一)數(shù)據(jù)同步的流程
當(dāng)系統(tǒng)業(yè)務(wù)調(diào)用和后臺(tái)數(shù)據(jù)配置變化時(shí),主數(shù)據(jù)庫中的內(nèi)容發(fā)生變化,同時(shí)將變化寫入對(duì)應(yīng)表的映象區(qū)中,當(dāng)實(shí)時(shí)同步進(jìn)程啟動(dòng)時(shí),在傳輸控制數(shù)據(jù)區(qū)的控制,讀取映象區(qū)中的消息,將記錄打包發(fā)往傳輸層。接受端數(shù)據(jù)庫,接受到數(shù)據(jù)后解包,檢查數(shù)據(jù)并更新記錄,如果成功,返回成功消息,發(fā)送端傳輸下一包;如果不成功,返回失敗消息,發(fā)送端繼續(xù)傳輸此包。如果在指定時(shí)間內(nèi),未有消息返回,也認(rèn)為是不成功。具體步驟如下:
1、初始化數(shù)據(jù)庫的映象區(qū),傳輸數(shù)據(jù)控制區(qū);
2、主數(shù)據(jù)庫發(fā)生變化時(shí),將變化表的變化記錄號(hào)寫入相應(yīng)表的隊(duì)列,并在相應(yīng)映象區(qū)描述對(duì)應(yīng)的變化:
3、當(dāng)定時(shí)周期到時(shí),啟動(dòng)實(shí)時(shí)同步進(jìn)程,將記錄打包發(fā)送到接受端數(shù)據(jù)庫,同時(shí)將映象區(qū)和隊(duì)列中的相應(yīng)記錄刪除:
4、接受端數(shù)據(jù)庫接受數(shù)據(jù),并更新相應(yīng)表記錄,返回應(yīng)答消息;
5、收到同步確認(rèn)后,繼續(xù)同步其他數(shù)據(jù),如收到同步失敗或在指定時(shí)間內(nèi)未收到響應(yīng)消息,則可以重傳一定次數(shù);
6、若在指定次數(shù)內(nèi),重復(fù)3-5,直到同步結(jié)束,則等待下次時(shí)間周期,開始同步。
若未同步完成,因?yàn)槌掷m(xù)同步而可能影響其他操作的執(zhí)行也要停止同步,在下一次同步啟動(dòng)時(shí)從當(dāng)前記錄處開始同步。
(二)內(nèi)存數(shù)據(jù)庫的并發(fā)性
數(shù)據(jù)庫將面對(duì)成百上千個(gè)用戶,這樣必然存在多個(gè)用戶并發(fā)地存取同一個(gè)數(shù)據(jù)庫的情況。在這種情況下,由于相互間的干擾,可能會(huì)產(chǎn)生錯(cuò)誤的總體結(jié)果。本文采取的做法是在分布式的內(nèi)存數(shù)據(jù)系統(tǒng)中采取一定的并發(fā)控制機(jī)制,使得一個(gè)事務(wù)的執(zhí)行不受其它事務(wù)的干擾,從而避免并發(fā)事務(wù)造成實(shí)據(jù)的不一致。本文的調(diào)度策略是:基于優(yōu)先級(jí)任務(wù)的搶占式調(diào)度和基于時(shí)間片輪轉(zhuǎn)進(jìn)程的順序調(diào)度。并發(fā)性控制只要保證不同的事務(wù)串行執(zhí)行;0s在同一個(gè)任務(wù)內(nèi)的進(jìn)程將被順序調(diào)度;除非自動(dòng)放棄CPU控制權(quán)(通過顯式調(diào)用OS原語)[4]。只要保證對(duì)數(shù)據(jù)庫的直接訪問的進(jìn)程全部在同一個(gè)任務(wù)中,那么就有效地解決了數(shù)據(jù)庫訪問的并發(fā)性問題。
首先,所有數(shù)據(jù)的存取有一個(gè)過程集實(shí)現(xiàn),過程集中的若干過程依序組合完成一個(gè)事務(wù),由于任務(wù)之間存在優(yōu)先級(jí)的任務(wù)搶占問題,即使優(yōu)先級(jí)相同也存在按時(shí)間片輪轉(zhuǎn)的問題。這些問題都直接要求任務(wù)的進(jìn)程在存取數(shù)據(jù)時(shí)不能直接調(diào)用過程集中的過程,而只能將事務(wù)交給任務(wù)的進(jìn)程來完成這個(gè)事務(wù)。采用這個(gè)方式既保證處理的實(shí)時(shí)性,又將事務(wù)串行化保證事務(wù)處理的完整性而沒有增加額外的開銷。對(duì)于處理任務(wù)的進(jìn)程使用void dbCall(WORDl6EventNo,LPSTR iParam,LPSTR oParam)存取數(shù)據(jù),對(duì)于其它任務(wù)的進(jìn)程使用void dbAccess(WORDl6 EventNo,LPSTR iParam,LPSTR oParam)存取數(shù)據(jù)。前者是一個(gè)純粹的過程調(diào)用,后者形式上是一個(gè)過程調(diào)用,其內(nèi)部實(shí)現(xiàn)是采用了進(jìn)程通信,保證事務(wù)的執(zhí)行在任務(wù)中完成,如圖3-1所示。
四、小結(jié)
本文所研究的內(nèi)存數(shù)據(jù)庫為每一種對(duì)象提供的方法都可以為其繼承者所使用,且該繼承者可以是另一種對(duì)象。由該對(duì)象說明的各個(gè)數(shù)據(jù)實(shí)例,都可以共用這些方法(如插入、刪除、查詢等方法),這大大地提高了代碼的使用效率及減少了具體數(shù)據(jù)實(shí)例的創(chuàng)建工作量。每一種由對(duì)象聲明的數(shù)據(jù)實(shí)例,可以通過重載修改其某些方法的執(zhí)行特性,這種表現(xiàn)稱為多態(tài)性。多態(tài)性為數(shù)據(jù)實(shí)例的方法更新與擴(kuò)展打開了方便之門。
總之,內(nèi)存數(shù)據(jù)庫內(nèi)各種數(shù)據(jù)的描述是采用關(guān)系型數(shù)據(jù)模式,采用面向?qū)ο蟮臄?shù)據(jù)庫設(shè)計(jì)方法將存儲(chǔ)信息的表有效地封裝起來,訪問者只有通過對(duì)象提供的基本方法才能接觸到數(shù)據(jù)的存儲(chǔ)實(shí)體,這有效地保證了數(shù)據(jù)存儲(chǔ)實(shí)體的安全性。