張曉偉
[摘要]數據庫系統本質上是一個用計算機存儲記錄的系統。作為數據庫的一個分支,內存數據庫能為實時性提供保障。針對內存數據庫的二維表、索引數據、單,向資源進行詳細的設計,并實現內存數據庫在應用過程中的數據同步及并發性應用。
[關鍵詞]內存數據庫數據同步分布式系統
中圖分類號:TP3文獻標識碼:A文章編號:1671—7597(2009)0210016--02
一、引言
內存數據庫系統是基于電話交換系統的。與傳統的外存數據庫相比,內存數據庫的最大特點是數據長期駐留于主存,作為主拷貝,而硬盤上的備份只用于轉存與恢復。所有對數據關系的檢索全部在內存完成,為實時性提供最大保障。同樣,由于數據長期駐留在內存中,數據組織方式、索引方式和操作序列化方式也是按照內存的特點做優化。

作為數據庫的一個分支,內存數據庫系統也支持當前流行的大型數據庫系統的一些流行設計思想,如數據字典(Data Dictionary)、光標操作(Cursor)、保持數據完整性、一致性的觸發器(Trigger)、虛刪除(softDelete)[1]。又由于內存數據庫系統通常都是多模塊系統,所以相應的要求內存數據庫具有一定的分布式數據庫的能力,完成分布式的資源管理。
二、內存數據庫的設計
(一)二維表對象
一個二維表是一個具體的二元關系。二維表的每一行稱為表的元組(Tuple)或記錄(Record),每一列稱為表的域(Domain)或字段(Field)。二維表中能確定唯一一條記錄的記錄字段集構成二維表的關鍵字(Key),一個二維表的關鍵字可能有多個,其中的一個稱為二維表的主關鍵字(Primarykey)。通常一個二維表的特征如表2-1所示:
表2-1中的描述內容包含兩部分:對象屬性和對象方法。對象的屬性描述了對象的基本特征,所有該對象的實例均具有這些特征。對象的方法規定了操縱對象實例的幾個基本方法,這些方法可能隨著二維表對象實例的不同而不同,因此,在設計對象方法時需要能夠在需要時重定義對象的方法,支持對象方法的重定義是內存數據庫系統設計的一個重要方面。
而索引對象和隊列對象都是建立在二維表對象基礎上的。一個具體的二維表對象實例在運行之前必須在系統注冊登記才能被系統識別。注冊定義一個具體的二維表的方法步驟如下,其中[]為可選部分,對于有些二維表不需要索引或隊列管理:注冊一個空表;在所注冊的空表中逐個增加字段;提供為所有二維表對象預定義的若干方法;為二維表建立存儲區;[注冊二維表的索引對象];[為索引建立存儲區];[注冊隊列對象]:[為隊列建立存儲區]。
(二)索引數據在內存中的表示
索引定義有兩類:順序索引、HASH索引[2]。對于順序索引,索引表的每個索引項由“索引關鍵字和索引記錄號”兩部分組成,索引表的索引項按“索引關鍵字”有序排列,如圖2-1所示,采用二分法檢索。在本系統中主要采用順序索引。
索引是給這些需要經常查找的字段維護一張索引表,索引表中的記錄有字段值(或者是字段值經過映射的信息)信息和相應記錄的位置(記錄號),字段值(或者是字段值經過映射的信息)作為索引記錄表的關鍵字。于是查找記錄可以通過先查找索引表獲得記錄號,然后就可以從表中獲得記錄。順序索引原理如圖2-2所示:
(三)表對象中單向資源隊列的處理
單向資源隊列在關系表中用于維護二維表數據區中空閑的內存塊信息。為此,在二維表對象中稱其為空閑隊列。此外,它還作為同步對象中的失步隊列用于記錄失步記錄。單向資源隊列對象是供表對象和同步對象內部使用的對象。單向資源隊列根據它在表對象和同步對象作用分別又稱為單向資源隊列對象和失步記錄隊列對象。表對象管理大量的記錄,這些一記錄是存放在一個記錄數組中的,當其中某些記錄刪除之后,存放相應記錄的內存就會空閑出來,當要向表插入記錄時,就需要知道那塊內存是空的,如果一個一個找顯然降低處理速度,為此就需要維護一個單向資源隊列,記錄空閑內存的位置[3]。在表對象中與單向資源隊列相關的操作的關鍵的有兩個:
1、當向表實例中插入記錄時,首先要刪除單向資源隊列隊尾元素,然后獲得空閑內存位置,再在該內存位置上寫入記錄內存。
2、當從表實例刪除記錄之后,要將給內存位置信息插入該單向資源隊列,以使該隊列記錄空閑內存位置。

此外,在表創建一個空閑對象實例并初始化該隊列和在表實例撤銷時,同時撤銷該隊列也是不可缺少的。
三、內存數據庫的應用
(一)數據同步的流程
當系統業務調用和后臺數據配置變化時,主數據庫中的內容發生變化,同時將變化寫入對應表的映象區中,當實時同步進程啟動時,在傳輸控制數據區的控制,讀取映象區中的消息,將記錄打包發往傳輸層。接受端數據庫,接受到數據后解包,檢查數據并更新記錄,如果成功,返回成功消息,發送端傳輸下一包;如果不成功,返回失敗消息,發送端繼續傳輸此包。如果在指定時間內,未有消息返回,也認為是不成功。具體步驟如下:
1、初始化數據庫的映象區,傳輸數據控制區;
2、主數據庫發生變化時,將變化表的變化記錄號寫入相應表的隊列,并在相應映象區描述對應的變化:
3、當定時周期到時,啟動實時同步進程,將記錄打包發送到接受端數據庫,同時將映象區和隊列中的相應記錄刪除:
4、接受端數據庫接受數據,并更新相應表記錄,返回應答消息;
5、收到同步確認后,繼續同步其他數據,如收到同步失敗或在指定時間內未收到響應消息,則可以重傳一定次數;
6、若在指定次數內,重復3-5,直到同步結束,則等待下次時間周期,開始同步。
若未同步完成,因為持續同步而可能影響其他操作的執行也要停止同步,在下一次同步啟動時從當前記錄處開始同步。
(二)內存數據庫的并發性
數據庫將面對成百上千個用戶,這樣必然存在多個用戶并發地存取同一個數據庫的情況。在這種情況下,由于相互間的干擾,可能會產生錯誤的總體結果。本文采取的做法是在分布式的內存數據系統中采取一定的并發控制機制,使得一個事務的執行不受其它事務的干擾,從而避免并發事務造成實據的不一致。本文的調度策略是:基于優先級任務的搶占式調度和基于時間片輪轉進程的順序調度。并發性控制只要保證不同的事務串行執行;0s在同一個任務內的進程將被順序調度;除非自動放棄CPU控制權(通過顯式調用OS原語)[4]。只要保證對數據庫的直接訪問的進程全部在同一個任務中,那么就有效地解決了數據庫訪問的并發性問題。
首先,所有數據的存取有一個過程集實現,過程集中的若干過程依序組合完成一個事務,由于任務之間存在優先級的任務搶占問題,即使優先級相同也存在按時間片輪轉的問題。這些問題都直接要求任務的進程在存取數據時不能直接調用過程集中的過程,而只能將事務交給任務的進程來完成這個事務。采用這個方式既保證處理的實時性,又將事務串行化保證事務處理的完整性而沒有增加額外的開銷。對于處理任務的進程使用void dbCall(WORDl6EventNo,LPSTR iParam,LPSTR oParam)存取數據,對于其它任務的進程使用void dbAccess(WORDl6 EventNo,LPSTR iParam,LPSTR oParam)存取數據。前者是一個純粹的過程調用,后者形式上是一個過程調用,其內部實現是采用了進程通信,保證事務的執行在任務中完成,如圖3-1所示。
四、小結
本文所研究的內存數據庫為每一種對象提供的方法都可以為其繼承者所使用,且該繼承者可以是另一種對象。由該對象說明的各個數據實例,都可以共用這些方法(如插入、刪除、查詢等方法),這大大地提高了代碼的使用效率及減少了具體數據實例的創建工作量。每一種由對象聲明的數據實例,可以通過重載修改其某些方法的執行特性,這種表現稱為多態性。多態性為數據實例的方法更新與擴展打開了方便之門。
總之,內存數據庫內各種數據的描述是采用關系型數據模式,采用面向對象的數據庫設計方法將存儲信息的表有效地封裝起來,訪問者只有通過對象提供的基本方法才能接觸到數據的存儲實體,這有效地保證了數據存儲實體的安全性。