李大明
(鐵道部 信息技術(shù)中心,北京 100844)
隨著嵌入式系統(tǒng)的廣泛應(yīng)用及用戶對(duì)數(shù)據(jù)處理和數(shù)據(jù)管理能力的不斷提高,嵌入式數(shù)據(jù)庫(kù)技術(shù)得到快速發(fā)展。嵌入式數(shù)據(jù)庫(kù)不僅具有傳統(tǒng)數(shù)據(jù)庫(kù)的主要功能,還具有操作簡(jiǎn)單、快捷靈活等特性。該技術(shù)屏蔽了傳統(tǒng)數(shù)據(jù)庫(kù)需要與服務(wù)器配置相關(guān)的資源開(kāi)銷,可以直接嵌入到應(yīng)用進(jìn)程中,對(duì)數(shù)據(jù)庫(kù)進(jìn)行處理?;谇度胧疥P(guān)系數(shù)據(jù)庫(kù)存儲(chǔ)的貨運(yùn)雜費(fèi)收繳管理系統(tǒng)可以提高貨運(yùn)雜費(fèi)收繳的效率,加快鐵路貨運(yùn)管理信息化的進(jìn)程,已成為鐵路貨運(yùn)現(xiàn)代化管理的中堅(jiān)力量。
鐵路貨物運(yùn)輸雜費(fèi)是鐵路貨物運(yùn)輸費(fèi)用的組成部分。貨物自承運(yùn)至交付的全過(guò)程中,鐵路運(yùn)輸企業(yè)向托運(yùn)人、收貨人提供的輔助作業(yè)和勞務(wù),以及托運(yùn)人或收貨人額外占用鐵路設(shè)備,使用用具、備品所發(fā)生的費(fèi)用等,均屬貨運(yùn)雜費(fèi)。
鐵路貨運(yùn)雜費(fèi)收繳系統(tǒng)具有到達(dá)貨票接收、發(fā)送雜費(fèi)補(bǔ)收、到達(dá)貨物交付、雜費(fèi)核收、客戶預(yù)付款管理、催領(lǐng)通知打印、進(jìn)款結(jié)賬、分類統(tǒng)計(jì)等功能。對(duì)裝卸費(fèi)的核收,貨車使用費(fèi)的核收,取送車費(fèi)的核收、內(nèi)外勤交接等提供專用處理模塊。滿足車站多樣化的需求。
貨運(yùn)雜費(fèi)收繳系統(tǒng)作為基礎(chǔ)雜費(fèi)收繳工具,在基層分為單機(jī)工作模式和服務(wù)器工作模式,同時(shí)對(duì)鐵路局、鐵道部層次具有傳輸接口,其體系結(jié)構(gòu)如圖1。
1.3.1 軟件登陸
進(jìn)入本系統(tǒng)的接口,校驗(yàn)用戶名稱、口令,用戶登錄需要選擇工作日期,校驗(yàn)成功后進(jìn)入系統(tǒng)。
1.3.2 系統(tǒng)設(shè)置模塊
系統(tǒng)設(shè)置模塊完成一組與本系統(tǒng)運(yùn)行信息相關(guān)的功能,包括:業(yè)務(wù)崗位設(shè)置、操作員設(shè)置、系統(tǒng)運(yùn)行車站設(shè)置、系統(tǒng)運(yùn)行模式設(shè)置、修改當(dāng)前操作員口令、變更操作員和系統(tǒng)日志查詢等功能。
1.3.3 到達(dá)處理模塊
完成到達(dá)貨票接收、到達(dá)貨票錄入、到達(dá)貨票確認(rèn)、到達(dá)貨票催領(lǐng)和到達(dá)貨物交接等操作。
1.3.4 業(yè)務(wù)處理模塊
在貨票完成到達(dá)處理作業(yè)環(huán)節(jié)后,即進(jìn)入業(yè)務(wù)處理環(huán)節(jié),包括:到達(dá)運(yùn)雜費(fèi)核收、發(fā)送運(yùn)雜費(fèi)核收、中間運(yùn)雜費(fèi)交付、貨車使用費(fèi)交付。
1.3.5 統(tǒng)計(jì)報(bào)告模塊
該模塊完成各種統(tǒng)計(jì)報(bào)表,包括:各種業(yè)務(wù)的瀏覽和統(tǒng)計(jì)。
1.3.6 預(yù)付款處理模塊
該模塊處理的是在到達(dá)運(yùn)雜費(fèi)核收模塊中付款方式選擇預(yù)付款交付產(chǎn)生的雜費(fèi)信息。預(yù)付款管理包括預(yù)付款存入、支付明細(xì)查詢、預(yù)付款扣款、預(yù)付款退補(bǔ)和預(yù)付款結(jié)帳等內(nèi)容。
1.3.7 參數(shù)維護(hù)模塊
參數(shù)字典維護(hù)是本系統(tǒng)中所涉及到的所有字典參數(shù)的維護(hù)。
貨運(yùn)雜費(fèi)收繳管理系統(tǒng)的本地存儲(chǔ)采用開(kāi)放源代碼的嵌入式關(guān)系數(shù)據(jù)庫(kù)SQLite,整個(gè)數(shù)據(jù)庫(kù)(定義、表、索引和數(shù)據(jù)本身)都存儲(chǔ)在一個(gè)單一的文件中,不需要管理員進(jìn)行數(shù)據(jù)庫(kù)軟件的維護(hù)。而網(wǎng)絡(luò)存儲(chǔ)采用Oracle8i同時(shí)支持Oracle7、Oracle9i版本數(shù)據(jù)庫(kù)。下面重點(diǎn)介紹本系統(tǒng)中本地存儲(chǔ)的嵌入式關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)。
嵌入式數(shù)據(jù)庫(kù)在某些方面與大型關(guān)系數(shù)據(jù)庫(kù)相似,它最大的特性是無(wú)須擁有獨(dú)立運(yùn)行的數(shù)據(jù)庫(kù)引擎,具有占用磁盤小,占有內(nèi)存少的特點(diǎn)。實(shí)際上嵌入式數(shù)據(jù)庫(kù)是一種具備了基本數(shù)據(jù)庫(kù)特性的若干數(shù)據(jù)文件。嵌入式數(shù)據(jù)庫(kù)編譯后的產(chǎn)品所占內(nèi)存一般不超過(guò)幾十kbit。
嵌入式數(shù)據(jù)庫(kù)將數(shù)據(jù)庫(kù)系統(tǒng)與操作系統(tǒng)和具體應(yīng)用集成在一起,運(yùn)行在各種智能嵌入式設(shè)備上。與傳統(tǒng)的數(shù)據(jù)庫(kù)系統(tǒng)相比,它體積小,有較強(qiáng)的便攜性和易用性,以及較為完備的功能來(lái)實(shí)現(xiàn)用戶對(duì)數(shù)據(jù)的管理操作。在實(shí)際應(yīng)用中,嵌入式數(shù)據(jù)庫(kù)存儲(chǔ)容量較小、穩(wěn)定性和可靠性比較低,我們可以在PC機(jī)上配置嵌入式數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)大容量數(shù)據(jù)的存儲(chǔ)和管理。
從結(jié)構(gòu)上可以將嵌入式數(shù)據(jù)庫(kù)管理系統(tǒng)分為外殼和內(nèi)核兩大部分。
2.2.1 外 殼
嵌入式數(shù)據(jù)庫(kù)提供可直接調(diào)用的內(nèi)部接口函數(shù),開(kāi)發(fā)人員可以通過(guò)接口函數(shù)對(duì)數(shù)據(jù)庫(kù)直接進(jìn)行管理和訪問(wèn)。數(shù)據(jù)庫(kù)應(yīng)用程序是數(shù)據(jù)管理體系與終端的中間層,數(shù)據(jù)庫(kù)應(yīng)用開(kāi)發(fā)人員在本層進(jìn)行編碼工作,完成對(duì)嵌入式數(shù)據(jù)庫(kù)的訪問(wèn)鏈接。
開(kāi)發(fā)人員在使用數(shù)據(jù)庫(kù)系統(tǒng)向上提供的接口函數(shù)時(shí),只需要調(diào)用標(biāo)準(zhǔn)的接口,不需要考慮下層的實(shí)現(xiàn)細(xì)節(jié)。其主要工作是對(duì)接口函數(shù)的輸入項(xiàng)進(jìn)行處理,然后將需要處理的輸入項(xiàng)轉(zhuǎn)化為數(shù)據(jù)庫(kù)內(nèi)部可處理的數(shù)據(jù)結(jié)構(gòu)。
2.2.2 內(nèi) 核
這部分是嵌入式數(shù)據(jù)庫(kù)的內(nèi)核,包含了嵌入式數(shù)據(jù)庫(kù)的核心功能。主要有:系統(tǒng)管理、事務(wù)管理器等。具體內(nèi)容本文不做詳細(xì)介紹。
本系統(tǒng)存儲(chǔ)工具采用了開(kāi)放源代碼的SQLite嵌入式關(guān)系數(shù)據(jù)庫(kù),在基于源代碼的基礎(chǔ)上定義了一些結(jié)構(gòu)性的宏,這樣既可以支持中間層的接口定義,也方便調(diào)用管理。而在數(shù)據(jù)存儲(chǔ)中采用壓縮、加密技術(shù),通過(guò)中間層對(duì)原始數(shù)據(jù)進(jìn)行壓縮及加密。上層的應(yīng)用進(jìn)程通過(guò)調(diào)用中間層實(shí)現(xiàn)對(duì)數(shù)據(jù)的訪問(wèn),保護(hù)原始數(shù)據(jù)不被惡意篡改,因而保證了數(shù)據(jù)的安全性和完整性。數(shù)據(jù)結(jié)構(gòu)如圖2。
圖2 數(shù)據(jù)結(jié)構(gòu)
2.3.1 設(shè)計(jì)策略
整個(gè)數(shù)據(jù)存儲(chǔ)涉及到的兩種數(shù)據(jù):字典數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)。設(shè)計(jì)策略包含數(shù)據(jù)存儲(chǔ)策略、數(shù)據(jù)訪問(wèn)策略等。
2.3.1.1 數(shù)據(jù)存儲(chǔ)策略
針對(duì)不同的數(shù)據(jù)采取不同的存儲(chǔ)方案:(1)對(duì)于字典數(shù)據(jù),按照不同的維護(hù)層次(部級(jí)字典、局級(jí)字典、站段級(jí)字典(含地鐵公司)、窗口級(jí)字典)分別存儲(chǔ)到相對(duì)獨(dú)立的本地?cái)?shù)據(jù)文件中,窗口級(jí)字典不上傳到網(wǎng)絡(luò),其他字典在網(wǎng)絡(luò)上分開(kāi)存放,每一級(jí)維護(hù)的參數(shù)原則上存儲(chǔ)在一個(gè)該級(jí)對(duì)應(yīng)的本地?cái)?shù)據(jù)庫(kù)中。(2)對(duì)于雜費(fèi)業(yè)務(wù)數(shù)據(jù),本地按照工作日分開(kāi)存儲(chǔ),網(wǎng)絡(luò)按工作庫(kù)/歷史庫(kù)存儲(chǔ),工作庫(kù)保存1個(gè)月~2個(gè)月,歷史庫(kù)保存1年~2年。為保證數(shù)據(jù)的安全性和完整性,本地?cái)?shù)據(jù)存儲(chǔ)在兩個(gè)不同的目錄下,每次寫數(shù)據(jù)時(shí)同時(shí)寫入兩個(gè)本地?cái)?shù)據(jù)庫(kù),如果網(wǎng)絡(luò)存儲(chǔ)狀態(tài)正常,同步寫入網(wǎng)絡(luò)數(shù)據(jù)庫(kù),有服務(wù)器而網(wǎng)絡(luò)不通時(shí),把數(shù)據(jù)的變化寫入日志,待網(wǎng)絡(luò)連通時(shí),自動(dòng)實(shí)現(xiàn)數(shù)據(jù)上傳到網(wǎng)絡(luò)服務(wù)器。本地?cái)?shù)據(jù)與工作庫(kù)由接口程序?qū)崿F(xiàn)同步,工作庫(kù)到歷史庫(kù)由具有管理權(quán)限的操作員控制數(shù)據(jù)倒庫(kù)。
2.3.1.2 數(shù)據(jù)訪問(wèn)策略
字典數(shù)據(jù)每個(gè)維護(hù)層次只能修改自己負(fù)責(zé)的數(shù)據(jù),對(duì)于由其他層次維護(hù)的字典數(shù)據(jù)只能讀取。
業(yè)務(wù)數(shù)據(jù)來(lái)自最基層,所以只能由車站級(jí)雜費(fèi)軟件建立和修改,其他授權(quán)系統(tǒng)只能讀取,未授權(quán)系統(tǒng)不能讀取。業(yè)務(wù)數(shù)據(jù)只能從窗口本地上傳到服務(wù)器,不允許服務(wù)器數(shù)據(jù)覆蓋本地?cái)?shù)據(jù),恢復(fù)客戶機(jī)時(shí)應(yīng)有管理員權(quán)限。
查詢數(shù)據(jù)時(shí),根據(jù)系統(tǒng)運(yùn)行模式確定所要查詢的數(shù)據(jù)庫(kù)是本地?cái)?shù)據(jù)庫(kù)還是網(wǎng)絡(luò)數(shù)據(jù)庫(kù)。
貨票本地?cái)?shù)據(jù)庫(kù)文件、雜費(fèi)本地?cái)?shù)據(jù)庫(kù)、字典本地?cái)?shù)據(jù)庫(kù)分別在不同的目錄中存儲(chǔ)。
網(wǎng)絡(luò)數(shù)據(jù)庫(kù)中數(shù)據(jù)表名稱由電報(bào)碼和標(biāo)識(shí)符號(hào)組成(不按時(shí)間區(qū)分表名)。本地?cái)?shù)據(jù)庫(kù)中表名與網(wǎng)絡(luò)服務(wù)器表名相同。
2.3.2 數(shù)據(jù)元素
貨票數(shù)據(jù)包含本站發(fā)送貨票和到達(dá)貨票,也包括地鐵公司運(yùn)行的貨物在到站填制的貨票。
接收電子票直接存入工作庫(kù),接收時(shí)比較數(shù)據(jù)狀態(tài),如果庫(kù)中數(shù)據(jù)已經(jīng)做過(guò)處理,不能直接進(jìn)行覆蓋。數(shù)據(jù)元素主要包括貨票數(shù)據(jù)、雜費(fèi)數(shù)據(jù)、部級(jí)字典、局級(jí)字典、站段字典、操作日志。具體數(shù)據(jù)結(jié)構(gòu)省略。
3.1.1 數(shù)據(jù)結(jié)構(gòu)
貨運(yùn)雜費(fèi)收繳管理系統(tǒng)根據(jù)嵌入式數(shù)據(jù)庫(kù)基本功能的特點(diǎn),將系統(tǒng)中所有的數(shù)據(jù)分為數(shù)據(jù)表、數(shù)據(jù)表索引和資源隊(duì)列。并由此定義了相應(yīng)的數(shù)據(jù)對(duì)象:二維表對(duì)象、表索引對(duì)象和隊(duì)列對(duì)象。對(duì)于每一種對(duì)象,都有相應(yīng)的特征描述來(lái)規(guī)定該對(duì)象的共有特性以及實(shí)現(xiàn)的基本方法。
3.1.2 存儲(chǔ)管理實(shí)現(xiàn)
貨運(yùn)雜費(fèi)收繳管理系統(tǒng)的數(shù)據(jù)庫(kù)由若干表組成,每個(gè)表對(duì)應(yīng)的表空間在內(nèi)存中采用虛擬文件來(lái)存儲(chǔ),通過(guò)對(duì)存儲(chǔ)空間的起始地址、結(jié)束地址及鏈表的記錄管理,實(shí)現(xiàn)對(duì)這些表的存儲(chǔ)空間進(jìn)行有效的管理。把這些虛擬文件的連續(xù)存儲(chǔ)空間按頁(yè)面存儲(chǔ),每個(gè)頁(yè)面可以存儲(chǔ)多條記錄。對(duì)于頁(yè)面大小的處理,可以根據(jù)記錄的大小及記錄數(shù)來(lái)控制。因此,當(dāng)對(duì)數(shù)據(jù)庫(kù)中一條記錄進(jìn)行修改操作時(shí),只需要將虛擬文件中這條記錄所在的頁(yè)面修改即可。
3.1.3 提供的接口函數(shù)
cache_init 緩沖初始化:為表分配頁(yè)面,并將該表加入到緩沖表中,同時(shí)初始化。
cache_free 清空緩沖區(qū):釋放表的所存在的頁(yè)面,然后釋放表所占的緩存。
cache_load 文件裝載:從磁盤中將表對(duì)應(yīng)的文件數(shù)據(jù)全部讀到表的相應(yīng)頁(yè)面中。
cache_write 寫入文件:將表中的節(jié)點(diǎn)鏈表中數(shù)據(jù)寫到對(duì)應(yīng)磁盤的文件。
cache_addpg 擴(kuò)展節(jié)點(diǎn):添加一個(gè)新節(jié)點(diǎn)。cache_delpg 刪除節(jié)點(diǎn):刪除節(jié)點(diǎn)。
cache_redpg 讀取一頁(yè):從數(shù)據(jù)中讀取指定一頁(yè)內(nèi)容。
cache_outpg 寫入一頁(yè):將指定一頁(yè)數(shù)據(jù)寫到文件中。
嵌入式數(shù)據(jù)庫(kù)SQLite的C語(yǔ)言API以下面3個(gè)核心函數(shù)為基礎(chǔ):
sqlite *sqlite_open(const char *dbname,int mode,char **errmsg);
Void sqlite_close(sqlite *db);
Int sqlite_exec(sqlite *db,char *sql,int(*callback)(void *,int,char **,char**),void *parg,char**errmsg);
其中,前兩個(gè)函數(shù)用于打開(kāi)與關(guān)閉數(shù)據(jù)庫(kù),sqlite_exec函數(shù)用來(lái)處理sql查詢,所用callback函數(shù)由用戶編寫,用來(lái)接收查詢結(jié)果,查詢結(jié)果的每一條記錄都會(huì)調(diào)用一次callback函數(shù),正常返回0,如果非0,則查詢失敗。
雜費(fèi)收繳管理系統(tǒng)基于SQLite提供的接口函數(shù)封裝了一個(gè)中間層,該層完成了對(duì)數(shù)據(jù)的壓縮和編碼加密,然后存入數(shù)據(jù)庫(kù)。所以,用標(biāo)準(zhǔn)SQL語(yǔ)言從數(shù)據(jù)庫(kù)中查尋的結(jié)果是亂碼,只有通過(guò)中間層訪問(wèn),解壓縮再解密后才能得到原始數(shù)據(jù),這樣就保證了數(shù)據(jù)的安全性和完整性。其中,編碼采用Base64編碼,Base64編碼把任意序列的字節(jié)描述為一種不易被人直接識(shí)別的形式。通過(guò)編碼和加密后的數(shù)據(jù)所占的存儲(chǔ)空間變大,所以利用壓縮技術(shù)減少數(shù)據(jù)所占的空間。
中間層分別定義了壓縮和加密函數(shù),如下:
compress(Bytef *dest,uLongf *destLen,const Bytef *source,uLong sourceLen);
int Base64Encode(const unsigned char *src,int srclen, unsigned char *dest);
使用Base64Encode函數(shù)時(shí),應(yīng)注意要分別記錄數(shù)據(jù)壓縮前后的長(zhǎng)度,否則在解壓時(shí)無(wú)法還原。
中間層中還定義了數(shù)據(jù)庫(kù)相關(guān)類CppSQLite3DB和CppSQLite3Statement。類中的方法基于SQLite提供的API函數(shù),構(gòu)造了對(duì)數(shù)據(jù)庫(kù)訪問(wèn)的實(shí)現(xiàn)。
舉例說(shuō)明插入表的代碼如下:
通過(guò)以上代碼就完成了雜費(fèi)收繳管理系統(tǒng)中對(duì)原始數(shù)據(jù)進(jìn)行壓縮、編碼再插入到數(shù)據(jù)庫(kù)表的功能實(shí)現(xiàn)。同樣,可以完成對(duì)嵌入式數(shù)據(jù)庫(kù)中數(shù)據(jù)的刪除和更新等功能的實(shí)現(xiàn)。
3.3.1 事務(wù)管理的實(shí)現(xiàn)
貨運(yùn)雜費(fèi)收繳管理系統(tǒng)將所有任務(wù)的事務(wù)狀態(tài)分為3種:開(kāi)始提交(向系統(tǒng)文件提交修改過(guò)的數(shù)據(jù)頁(yè)面)、正在提交(向數(shù)據(jù)文件提交修改過(guò)的數(shù)據(jù)頁(yè)面)和事務(wù)空閑(沒(méi)有開(kāi)始事務(wù))。事務(wù)處理包括開(kāi)始事務(wù)、提交事務(wù)、事務(wù)回滾等功能。當(dāng)事務(wù)回滾時(shí),將任務(wù)日志中所有修改過(guò)的數(shù)據(jù)頁(yè)面回退,把修改的記錄還原。當(dāng)提交事務(wù)時(shí),將任務(wù)日志中修改過(guò)的數(shù)據(jù)頁(yè)面寫入到系統(tǒng)日志文件中。多個(gè)任務(wù)的事務(wù)同時(shí)提交時(shí),事物彼此間是互斥的,優(yōu)先處理優(yōu)先級(jí)高的事物。
3.3.2 日志設(shè)計(jì)與實(shí)現(xiàn)
貨運(yùn)雜費(fèi)收繳管理系統(tǒng)中存在兩種日志:系統(tǒng)日志文件和任務(wù)日志,系統(tǒng)日志文件只有一個(gè),用于處理并發(fā)事物時(shí)使用;而任務(wù)日志文件每個(gè)任務(wù)生成一個(gè),用于記錄本任務(wù)的修改操作。對(duì)于每一個(gè)事物,都有一個(gè)日志記錄任務(wù)所修改過(guò)的虛擬文件和數(shù)據(jù)頁(yè)面號(hào)。當(dāng)提交事務(wù)時(shí),依據(jù)任務(wù)日志記錄的內(nèi)容記入系統(tǒng)日志文件,當(dāng)回滾事務(wù)時(shí),依據(jù)任務(wù)日志恢復(fù)所有修改過(guò)的數(shù)據(jù)頁(yè)面。
基于嵌入式關(guān)系數(shù)據(jù)庫(kù)存儲(chǔ)的貨運(yùn)雜費(fèi)管理系統(tǒng)技術(shù)先進(jìn)、結(jié)構(gòu)合理、功能完善、安全可靠。該系統(tǒng)的使用有助于降低鐵路運(yùn)營(yíng)成本、強(qiáng)化精細(xì)管理、提高作業(yè)效率,為鐵路貨運(yùn)服務(wù)提供了強(qiáng)有力的保障。
[1]鐵道部. 鐵路貨物運(yùn)輸規(guī)程[M]. 北京:中國(guó)鐵道出版社,2011,4.
[2]鐵道部. 鐵路貨物運(yùn)輸管理規(guī)則[M]. 北京:中國(guó)鐵道出版社,2000,9.
[3]鐵道部. 鐵路運(yùn)輸收入票據(jù)管理工作規(guī)則[M]. 北京:中國(guó)鐵道出版社,2003,1.
[4]解 輝. 嵌入式數(shù)據(jù)庫(kù)實(shí)現(xiàn)原理[DB/OL]. http://www.docin.com/p-332516826.html, 2008-07-01.