VFP9中新的數(shù)據(jù)類型是如何影響DBF文件的

字號:

新的數(shù)據(jù)類型是如何影響 DBF 文件的
    你也許會對VFP是如何在表中實現(xiàn)這些新的數(shù)據(jù)類型感興趣。DBF結(jié)構(gòu)并不允許可變長度的字段,因此事實上在DBF表里的 Varchar 和 Varbinary 字段其實是被填補上空格的。因此,Microsoft 已經(jīng)有了一種跟蹤 Varchar 和 Varbinary 字段的長度的機制,以保證當需要的時候返回經(jīng)過正確的 Trim 的值。這里是它的工作方式:
    × 在所有版本 VFP 的DBF表中,如果其中某個字段可以接受 Null 值,那么這個表都會被增加一個隱藏的字段,名叫 _NullFlags。該字段中包含一個位值(bit value),用于指示在一條指定記錄中的某個特定字段是否包含著一個 Null。例如,如果在一條記錄中的第一個可接收 null 的字段中包含一個 null,那么 _NullFlags 中的位0就被設(shè)置為1。如果第二個可接收 null 值的字段中包含一個非 null 值,那么 _NullFlags 中的位1就被設(shè)置0。由于一個字節(jié)中有8位,_NullFlag 中值的寬度為可接收 null 值字段的數(shù)量處以8。
    × 在 VFP 9 中,_NullFlags 服務(wù)于兩個責任:它的位還指示在 Varchar 和 Varbinary 字段中的值是否將字段填滿了。如果一個位包含0,則在一個字段中值的長度等于該字段的長度(這個字段是滿的)。如果這個位包含1,則值的長度小于字段的長度,這種情況下字段根據(jù)需要會被用空格填補,而且最后一位包含著字段的長度。例如,一個包含著“AB”這樣內(nèi)容的10位長度的Varchar 字段中,實際上包含的是“AB”后面跟上7個空格、再加上一個 CHR(2)(2代表值的長度),同時在 _NullsFlags 中該字段的位為1。
    ×如果一個字段既可以接收 null 值又是 Varchar 或者 Varbinary 類型的,那么會用兩位來表示一個字段。低的那位代表“滿”狀態(tài)、而高的那位代表 null 狀態(tài)。例如,一個可接收 null 的10位Varchar字段中包含著“AB”,它在 _NullFlags 中就用 01 來代表(0意味著不為 null,1意味著不滿),而同一個字段中如果是一個 null 值則用11來表示(null并且不滿)。
    這里是一個示例,用于演示 _NullFlags 在用于可接收 null 的字符型(Field3)、不能為 null 的 Varchar(Field2)、可以為 null 的 Varchar 字段(Field4)的情況下的各種值。位0代表 Field2 的“滿”狀態(tài),位1包含著 Field3 的 null 狀態(tài),位2包含著Field4的“滿”狀態(tài),而位3包含著 Field4 的 null 狀態(tài)。這個示例使用 VFP 自帶的 HexEdit 工具來展示 DBF 文件中的 binary 內(nèi)容。滾動到地址 000001C0 來察看表中這7條記錄的內(nèi)容。
    create table TestVarchar (Field1 C(1), Field2 V(1), Field3 C(1) null, ; Field4 V(1) null) insert into TestVarchar values ('A', 'A', 'A', 'A') && Record 20 41 41 41 41, _NullFlags 00000000 = 00 insert into TestVarchar values ('A', '', 'A', 'A') && Record 20 41 00 41 41, _NullFlags 00000001 = 01 insert into TestVarchar values ('A', 'A', 'A', '') && Record 20 41 41 41 00, _NullFlags 00000100 = 04 insert into TestVarchar values ('A', 'A', .NULL., 'A') && Record 20 41 41 20 41, _NullFlags 00000010 = 02 insert into TestVarchar values ('A', 'A', 'A', .NULL.) && Record 20 41 41 41 00, _NullFlags 00001100 = 0C insert into TestVarchar values ('A', 'A', .NULL., .NULL.) && Record 20 41 41 20 00, _NullFlags 00001110 = 0E insert into TestVarchar values ('A', '', .NULL., .NULL.) && Record 20 41 00 20 00, _NullFlags 00001111 = 0F use do home() + 'Tools\HexEdit\HexEdit' with 'TestVarchar.dbf'
    (在代碼的注釋中,在記錄中開頭的 20 表示該記錄沒有被刪除過,41 是字母“A”,00 指示在一個 Varchar 字段中的值的長度為0字節(jié),因為該字段為空或者 null,而在一個字符型字段中的 20 是一個空格,指示該字段為空或者 null。)
    Blob 字段不影響 DBF 文件的結(jié)構(gòu),因為它們會被使用跟通常的 Memo 字段一樣的格式儲存在一個 FPT 文件中。狐社
    DBF 的另一個改動:如果一個表中包含有這些新數(shù)據(jù)類型中的任何一種,指示表類型的第一個位中將包含著 0x32(decimal 類型的 50)(你可以使用 SYS(2029)來返回這個值)。結(jié)果,你就不能在過去版本的 VFP 中或者用 VFP ODBC 驅(qū)動打開這個表。
    Binary 索引
    VFP 程序員經(jīng)常會建立一個基于 DELETED() 函數(shù)的索引。這個 Tag 能得到 Rushmore 優(yōu)化,因為 VFP 不需要大量訪問磁盤來判定哪些記錄已經(jīng)被刪除了;它便于從索引中查找,看起來就好像從內(nèi)存的緩存中查找一樣(不過,在特定條件下,這樣的索引可能反而會拖慢 VFP的速度。詳情請見 Chris Probst 在 FoxPro Advisor 1999年五月刊上的文章。在 FoxPro Wiki 上也有幾個關(guān)于這個問題的主題;http://fox.wikis.com)。
    由于建立在 DELETED() 或者別的邏輯表達式基礎(chǔ)上的索引只可能包含兩個值中的一個(.T.或者.F.),Microsoft 發(fā)現(xiàn)他們可以改變這樣的一個索引被存儲在 CDX 文件中的途徑,結(jié)果產(chǎn)生了更小同時更快速的索引。于是,VFP 9 就有了一種新的索引類型:binary。
    為了建立一個 binary 索引,請給 INDEX 命令添加 BINARY 關(guān)鍵字。例如:
    index on DELETED() tag DELETED binary
    這里是關(guān)于 binary 索引的一些細節(jié):
    × Binary 索引可能會是一個比正常的索引小得多的、因此也就快得多的東西。TestBinaryIndex.PRG 建立了表,其中分別建立了基于 DELETED() 的一個普通的索引和一個 binary 索引。binary 索引要比普通的那個快90%。
    × Binary 索引的用途是 Rushmore 優(yōu)化。你不能在它們上面進行 SEEK、也不能對它們進行 SET ORDER。
    × 邏輯表達式的運算結(jié)果永遠不能為 null 值,不管是在建立索引的時候、還是在以后使用這個表的時候,否則會出錯。
    × 你不能在 INDEX 命令中使用 FOR、ASCENDING、DESCENDING、UNIQUE、或者 CANDIDATE 子句,并且在建立一個 binary 索引的時候不能建立一個 IDX 索引文件。
    × 按照 VFP 幫助(“Visual FoxPro Index Types”主題)的說法,VFP 根據(jù)返回記錄的數(shù)量是多余還是少于總記錄數(shù)量的 3%,為一個 binary 索引建立的 Rushmore 優(yōu)化位圖會更快或者更慢??傊?,這個限制由幾個事實而決定,包括總的記錄數(shù)量。象許多情況一樣,你需要在實際條件下測試以判定 binary 索引將會對你的查詢產(chǎn)生什么樣的影響。另一個 VFP 幫助主題“Index Based on Deleted Records”中有著關(guān)于 VFP 在各種條件下可以怎樣優(yōu)化的更多信息。
    總結(jié)
    給 VFP 9 新增加的數(shù)據(jù)類型可以使它比過去任何時候都輕松的與象 SQL Server 這樣的非本地數(shù)據(jù)庫一起工作,同時也在本地表中使用它們也非常有用。如果你需要在 General 字段中存儲圖像的話,Blob 字段尤其有用。Binary 索引能夠增強你的 SQL SELECT 語句的性能,盡管 VFP 過去就已經(jīng)超速了。