Paradox數據庫是一種桌面型數據庫,具有有效性檢查、參考完整性、口令保護、字段類型豐富等特點。但是在實際使用過程中,當數據庫引擎出現問題時,由于數據沒有全部寫入數據庫中,可能造成數據庫損壞。本文介紹Paradox數據庫的數據表即DB文件損壞時的修復辦法。
DB文件格式
Paradox數據表的損壞可分為兩種情況:一是數據表表頭損壞,數據根本讀不出來;二是數據塊鏈表出現問題,只能看見部分記錄。無論是上述哪種情況,只要DB文件中的記錄仍然存在(本文稱這種損壞為邏輯損壞),就有可能恢復數據。
要恢復數據,必須了解DB文件的格式。DB文件保存著一個數據表的數據記錄,DB文件里的第一個塊是表頭(塊),表頭后面跟著數據塊。DB文件的邏輯結構如下圖所示:
其中表頭(表頭中部分字段的描述如表1所示)包含第一個數據塊、最后一個數據塊和第一個自由塊的塊號。每個塊都有編號,在表頭后面的第一個塊號碼是1。全部塊(表頭除外)都有相同的大小,這意味著塊號能用來計算塊的偏移量:
塊偏移=塊長度×(塊號碼-1)+表頭長度
數據塊分塊頭和記錄兩部分,其中塊頭由數據塊的前6個字節組成。數據塊使用雙向鏈表進行組織,鏈表元素(或稱為節點)是塊頭的前4個字節,包含了下一個數據塊和前一個數據塊的塊號。在數據塊內,記錄順序存儲,記錄間沒有空隙,數據塊的塊頭中還包含了當前塊中最后一個記錄的偏移量。表2是數據塊格式描述。
其中最后一個記錄的偏移量和塊頭部的末端相關,并以塊號加6計算偏移量。
分析問題
有了表的結構知識,我們就可以用它來分析數據表損壞的原因,從而找出修復數據表的方法。
當數據表邏輯損壞時,如果數據庫引擎報告表索引頭錯誤,通過分析可知多半是表頭中有關塊或記錄的參數不匹配,比如“使用的塊數”大于“總的塊數”,或是記錄數和塊數不匹配。如果只能顯示部分數據,可能是表頭中“總的記錄數”小于實際記錄數,也可能是數據塊鏈表錯亂。
如果只是表頭索引參數出了問題,我們可以通過分析表頭相關信息,用16進制編輯器直接進行參數修改就可解決問題;如果是數據塊鏈表出了問題,一般無法直接修改(比如對有成千上萬條記錄的數據表)。
筆者的方法是采用冗余方式計算鏈表,即數據塊和記錄都按最大數進行處理。每個數據塊中記錄的最大數跟數據塊大小和記錄長度有關,其關系為:記錄數(max)=[數據塊大小÷記錄長度]([]表示取運算結果的整數部分);而數據塊的多少又跟DB文件大小有關,其關系為:數據塊數(max)=(文件大小-塊頭大小)÷數據塊大小(這一運算結果應為整數,如果不為整數則取不小于它的最小整數)。以計算出來的兩個數據修改表頭索引參數,然后再根據表頭參數將鏈表修復為順序結構鏈表。到此為止,可以說基本上修復了數據表。不過,這樣一來表中就可能出現重復數據或無用數據,因此還要對數據表進行排序、刪除重復記錄等處理,然后就可以得到一個比較完美的數據表。
編程實現
下面給出用C++ Builder編程來修改表頭索引和數據塊鏈表的主要源代碼。需要注意的是,該方法不適用于有密碼的數據表。
用C++ Builder 新建一個工程,在窗體上創建一個OpenDialog1組件和一個Button1組件,并將OpenDialog1的Filter屬性設置為“*.DB|*.DB”,然后在Button1的OnClick事件中加入以下代碼:
|
(T114)