李大明
(鐵道部 信息技術中心,北京 100844)
隨著嵌入式系統的廣泛應用及用戶對數據處理和數據管理能力的不斷提高,嵌入式數據庫技術得到快速發展。嵌入式數據庫不僅具有傳統數據庫的主要功能,還具有操作簡單、快捷靈活等特性。該技術屏蔽了傳統數據庫需要與服務器配置相關的資源開銷,可以直接嵌入到應用進程中,對數據庫進行處理。基于嵌入式關系數據庫存儲的貨運雜費收繳管理系統可以提高貨運雜費收繳的效率,加快鐵路貨運管理信息化的進程,已成為鐵路貨運現代化管理的中堅力量。
鐵路貨物運輸雜費是鐵路貨物運輸費用的組成部分。貨物自承運至交付的全過程中,鐵路運輸企業向托運人、收貨人提供的輔助作業和勞務,以及托運人或收貨人額外占用鐵路設備,使用用具、備品所發生的費用等,均屬貨運雜費。
鐵路貨運雜費收繳系統具有到達貨票接收、發送雜費補收、到達貨物交付、雜費核收、客戶預付款管理、催領通知打印、進款結賬、分類統計等功能。對裝卸費的核收,貨車使用費的核收,取送車費的核收、內外勤交接等提供專用處理模塊。滿足車站多樣化的需求。
貨運雜費收繳系統作為基礎雜費收繳工具,在基層分為單機工作模式和服務器工作模式,同時對鐵路局、鐵道部層次具有傳輸接口,其體系結構如圖1。
1.3.1 軟件登陸
進入本系統的接口,校驗用戶名稱、口令,用戶登錄需要選擇工作日期,校驗成功后進入系統。
1.3.2 系統設置模塊
系統設置模塊完成一組與本系統運行信息相關的功能,包括:業務崗位設置、操作員設置、系統運行車站設置、系統運行模式設置、修改當前操作員口令、變更操作員和系統日志查詢等功能。
1.3.3 到達處理模塊
完成到達貨票接收、到達貨票錄入、到達貨票確認、到達貨票催領和到達貨物交接等操作。
1.3.4 業務處理模塊
在貨票完成到達處理作業環節后,即進入業務處理環節,包括:到達運雜費核收、發送運雜費核收、中間運雜費交付、貨車使用費交付。
1.3.5 統計報告模塊
該模塊完成各種統計報表,包括:各種業務的瀏覽和統計。
1.3.6 預付款處理模塊
該模塊處理的是在到達運雜費核收模塊中付款方式選擇預付款交付產生的雜費信息。預付款管理包括預付款存入、支付明細查詢、預付款扣款、預付款退補和預付款結帳等內容。
1.3.7 參數維護模塊
參數字典維護是本系統中所涉及到的所有字典參數的維護。
貨運雜費收繳管理系統的本地存儲采用開放源代碼的嵌入式關系數據庫SQLite,整個數據庫(定義、表、索引和數據本身)都存儲在一個單一的文件中,不需要管理員進行數據庫軟件的維護。而網絡存儲采用Oracle8i同時支持Oracle7、Oracle9i版本數據庫。下面重點介紹本系統中本地存儲的嵌入式關系數據庫設計。
嵌入式數據庫在某些方面與大型關系數據庫相似,它最大的特性是無須擁有獨立運行的數據庫引擎,具有占用磁盤小,占有內存少的特點。實際上嵌入式數據庫是一種具備了基本數據庫特性的若干數據文件。嵌入式數據庫編譯后的產品所占內存一般不超過幾十kbit。
嵌入式數據庫將數據庫系統與操作系統和具體應用集成在一起,運行在各種智能嵌入式設備上。與傳統的數據庫系統相比,它體積小,有較強的便攜性和易用性,以及較為完備的功能來實現用戶對數據的管理操作。在實際應用中,嵌入式數據庫存儲容量較小、穩定性和可靠性比較低,我們可以在PC機上配置嵌入式數據庫來實現大容量數據的存儲和管理。
從結構上可以將嵌入式數據庫管理系統分為外殼和內核兩大部分。
2.2.1 外 殼
嵌入式數據庫提供可直接調用的內部接口函數,開發人員可以通過接口函數對數據庫直接進行管理和訪問。數據庫應用程序是數據管理體系與終端的中間層,數據庫應用開發人員在本層進行編碼工作,完成對嵌入式數據庫的訪問鏈接。
開發人員在使用數據庫系統向上提供的接口函數時,只需要調用標準的接口,不需要考慮下層的實現細節。其主要工作是對接口函數的輸入項進行處理,然后將需要處理的輸入項轉化為數據庫內部可處理的數據結構。
2.2.2 內 核
這部分是嵌入式數據庫的內核,包含了嵌入式數據庫的核心功能。主要有:系統管理、事務管理器等。具體內容本文不做詳細介紹。
本系統存儲工具采用了開放源代碼的SQLite嵌入式關系數據庫,在基于源代碼的基礎上定義了一些結構性的宏,這樣既可以支持中間層的接口定義,也方便調用管理。而在數據存儲中采用壓縮、加密技術,通過中間層對原始數據進行壓縮及加密。上層的應用進程通過調用中間層實現對數據的訪問,保護原始數據不被惡意篡改,因而保證了數據的安全性和完整性。數據結構如圖2。

圖2 數據結構
2.3.1 設計策略
整個數據存儲涉及到的兩種數據:字典數據和業務數據。設計策略包含數據存儲策略、數據訪問策略等。
2.3.1.1 數據存儲策略
針對不同的數據采取不同的存儲方案:(1)對于字典數據,按照不同的維護層次(部級字典、局級字典、站段級字典(含地鐵公司)、窗口級字典)分別存儲到相對獨立的本地數據文件中,窗口級字典不上傳到網絡,其他字典在網絡上分開存放,每一級維護的參數原則上存儲在一個該級對應的本地數據庫中。(2)對于雜費業務數據,本地按照工作日分開存儲,網絡按工作庫/歷史庫存儲,工作庫保存1個月~2個月,歷史庫保存1年~2年。為保證數據的安全性和完整性,本地數據存儲在兩個不同的目錄下,每次寫數據時同時寫入兩個本地數據庫,如果網絡存儲狀態正常,同步寫入網絡數據庫,有服務器而網絡不通時,把數據的變化寫入日志,待網絡連通時,自動實現數據上傳到網絡服務器。本地數據與工作庫由接口程序實現同步,工作庫到歷史庫由具有管理權限的操作員控制數據倒庫。
2.3.1.2 數據訪問策略
字典數據每個維護層次只能修改自己負責的數據,對于由其他層次維護的字典數據只能讀取。
業務數據來自最基層,所以只能由車站級雜費軟件建立和修改,其他授權系統只能讀取,未授權系統不能讀取。業務數據只能從窗口本地上傳到服務器,不允許服務器數據覆蓋本地數據,恢復客戶機時應有管理員權限。
查詢數據時,根據系統運行模式確定所要查詢的數據庫是本地數據庫還是網絡數據庫。
貨票本地數據庫文件、雜費本地數據庫、字典本地數據庫分別在不同的目錄中存儲。
網絡數據庫中數據表名稱由電報碼和標識符號組成(不按時間區分表名)。本地數據庫中表名與網絡服務器表名相同。
2.3.2 數據元素
貨票數據包含本站發送貨票和到達貨票,也包括地鐵公司運行的貨物在到站填制的貨票。
接收電子票直接存入工作庫,接收時比較數據狀態,如果庫中數據已經做過處理,不能直接進行覆蓋。數據元素主要包括貨票數據、雜費數據、部級字典、局級字典、站段字典、操作日志。具體數據結構省略。
3.1.1 數據結構
貨運雜費收繳管理系統根據嵌入式數據庫基本功能的特點,將系統中所有的數據分為數據表、數據表索引和資源隊列。并由此定義了相應的數據對象:二維表對象、表索引對象和隊列對象。對于每一種對象,都有相應的特征描述來規定該對象的共有特性以及實現的基本方法。
3.1.2 存儲管理實現
貨運雜費收繳管理系統的數據庫由若干表組成,每個表對應的表空間在內存中采用虛擬文件來存儲,通過對存儲空間的起始地址、結束地址及鏈表的記錄管理,實現對這些表的存儲空間進行有效的管理。把這些虛擬文件的連續存儲空間按頁面存儲,每個頁面可以存儲多條記錄。對于頁面大小的處理,可以根據記錄的大小及記錄數來控制。因此,當對數據庫中一條記錄進行修改操作時,只需要將虛擬文件中這條記錄所在的頁面修改即可。
3.1.3 提供的接口函數
cache_init 緩沖初始化:為表分配頁面,并將該表加入到緩沖表中,同時初始化。
cache_free 清空緩沖區:釋放表的所存在的頁面,然后釋放表所占的緩存。
cache_load 文件裝載:從磁盤中將表對應的文件數據全部讀到表的相應頁面中。
cache_write 寫入文件:將表中的節點鏈表中數據寫到對應磁盤的文件。
cache_addpg 擴展節點:添加一個新節點。cache_delpg 刪除節點:刪除節點。
cache_redpg 讀取一頁:從數據中讀取指定一頁內容。
cache_outpg 寫入一頁:將指定一頁數據寫到文件中。
嵌入式數據庫SQLite的C語言API以下面3個核心函數為基礎:
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);
其中,前兩個函數用于打開與關閉數據庫,sqlite_exec函數用來處理sql查詢,所用callback函數由用戶編寫,用來接收查詢結果,查詢結果的每一條記錄都會調用一次callback函數,正常返回0,如果非0,則查詢失敗。
雜費收繳管理系統基于SQLite提供的接口函數封裝了一個中間層,該層完成了對數據的壓縮和編碼加密,然后存入數據庫。所以,用標準SQL語言從數據庫中查尋的結果是亂碼,只有通過中間層訪問,解壓縮再解密后才能得到原始數據,這樣就保證了數據的安全性和完整性。其中,編碼采用Base64編碼,Base64編碼把任意序列的字節描述為一種不易被人直接識別的形式。通過編碼和加密后的數據所占的存儲空間變大,所以利用壓縮技術減少數據所占的空間。
中間層分別定義了壓縮和加密函數,如下:
compress(Bytef *dest,uLongf *destLen,const Bytef *source,uLong sourceLen);
int Base64Encode(const unsigned char *src,int srclen, unsigned char *dest);
使用Base64Encode函數時,應注意要分別記錄數據壓縮前后的長度,否則在解壓時無法還原。
中間層中還定義了數據庫相關類CppSQLite3DB和CppSQLite3Statement。類中的方法基于SQLite提供的API函數,構造了對數據庫訪問的實現。
舉例說明插入表的代碼如下:

通過以上代碼就完成了雜費收繳管理系統中對原始數據進行壓縮、編碼再插入到數據庫表的功能實現。同樣,可以完成對嵌入式數據庫中數據的刪除和更新等功能的實現。
3.3.1 事務管理的實現
貨運雜費收繳管理系統將所有任務的事務狀態分為3種:開始提交(向系統文件提交修改過的數據頁面)、正在提交(向數據文件提交修改過的數據頁面)和事務空閑(沒有開始事務)。事務處理包括開始事務、提交事務、事務回滾等功能。當事務回滾時,將任務日志中所有修改過的數據頁面回退,把修改的記錄還原。當提交事務時,將任務日志中修改過的數據頁面寫入到系統日志文件中。多個任務的事務同時提交時,事物彼此間是互斥的,優先處理優先級高的事物。
3.3.2 日志設計與實現
貨運雜費收繳管理系統中存在兩種日志:系統日志文件和任務日志,系統日志文件只有一個,用于處理并發事物時使用;而任務日志文件每個任務生成一個,用于記錄本任務的修改操作。對于每一個事物,都有一個日志記錄任務所修改過的虛擬文件和數據頁面號。當提交事務時,依據任務日志記錄的內容記入系統日志文件,當回滾事務時,依據任務日志恢復所有修改過的數據頁面。
基于嵌入式關系數據庫存儲的貨運雜費管理系統技術先進、結構合理、功能完善、安全可靠。該系統的使用有助于降低鐵路運營成本、強化精細管理、提高作業效率,為鐵路貨運服務提供了強有力的保障。
[1]鐵道部. 鐵路貨物運輸規程[M]. 北京:中國鐵道出版社,2011,4.
[2]鐵道部. 鐵路貨物運輸管理規則[M]. 北京:中國鐵道出版社,2000,9.
[3]鐵道部. 鐵路運輸收入票據管理工作規則[M]. 北京:中國鐵道出版社,2003,1.
[4]解 輝. 嵌入式數據庫實現原理[DB/OL]. http://www.docin.com/p-332516826.html, 2008-07-01.