DBMaker 的中文能力

作為國人獨力開發的第一套資料庫管理系統, DBMaker 的確具備與眾不同的中文能力

文/蔡耀祿

前言

目前市面上的資料庫軟體,雖然均宣稱其支援中文或中文化, 但其核心部份畢竟是由外國人所開發的中文化的工作, 大都僅能以外掛的方式來處理, 況且其主力市場並非中文地區, 故這些軟體所具備的中文能力均不完整。

DBMaker 資料庫管理系統 ( database management system, DBMS ) 在設計之初, 即確立了中文能力將會是 DBMaker 的一大特色, 開發過程中也極力支援中文, 在核心系統的設計上避免與中文有任何衝突, 所以 DBMaker 的中文能力絕對是同類軟體中的佼佼者。

本文便針對 DBMaker 的中文能力加以探討。

中文內碼編碼規則

處理中文最棘手的問題便是中文內碼種類繁多, 且不同的內碼有不同的編碼方式。為了瞭解 DBMaker 如何處理中文, 以下列出了較通用的中文內碼編碼方式, 以供參考。

內碼種類

編碼範圍

字數

高位元組

低位元組

BIG-5碼

81H∼FEH
共126個

40H∼7EH, A1H∼FEH
共157個

19782

通用碼

A1H∼FEH
共94個

A1H∼FEH, 21H∼7EH
共188個

17672

公會碼

81H∼FDH
共125個

30H∼39H, 41H∼5AH
61H∼7AH, 80H∼FDH
共188個

23500

倚天碼

81H∼AFH
DDH∼FEH
共81個

30H∼39H, 41H∼5AH
61H∼7AH, 80H∼FDH
共188個

15228

王安碼

8DH∼EEH
F0H∼FCH
共111個

30H∼39H, 41H∼5AH
61H∼7AH, 8DH∼EEH
F0H∼FCH
共173個

19203

IBM 5550碼

81H∼FCH
共124個

40H∼7EH, 80H∼FCH
共188個

23312

電信碼

A1H∼FEH
共94個

A1H∼FEH, 21H∼7EH
共188個

17672

漢英碼

81H∼AFH
B0H∼DEH
共94個

40H∼7EH, 80H∼FCH
共188個

17672

上述列表中的各種內碼編碼, 均以 2 個位元組 ( 2 Bytes ) 的表示法表示中文文字。

DBMaker 如何處理中文

由於 ASCII 碼定義了 26 個英文字母大小寫各一組,標點符號,以及一些控制碼 (如換行,換頁等), 大約僅有八十幾個字,因此在寫碼表示上,以 7 個位元 (bit) 可表示 128 個字的條件下, 已綽綽有餘。

也就是說, 若以一個位元組 (Byte) 8 個位元來處理 ASCII 字碼, 則其第 8 bit 可永遠為 0, 故所有的中文內碼便利用此特性來編碼。而由以上的中文內碼編碼規則便可看出, 所有中文碼的高位元組的第八個位元永遠為 1, 其主要目的是希望藉以與英文 ASCII 區隔。而低位元組便會與 ASCII 混用。由此可知, 判斷中英文的關鍵便在於高位元組的第八個位元。若為 0, 則為英文 ASCII 並以一個位元組來識別。再繼續處理下一個位元組; 若為 1, 則為中文, 須以 2 個位元組來處理, 故抓取下一個位元組以形成一個中文字, 這便是 DBMaker kernel 處理中文的基本原則。其演算法如下 :

     #define IS_CHINESE(x) ( (x) > 0x80 ) and ( (x) < 0xFF )

      While not end of text
        C1 = get_next_char ;
       If ( IS_CHINESE(C1) )
       {
        C2 = get_next_char ;
        C1, C2 form a Chinese char ;
        }
       else
        C1 forms an English char;
      End of while     

此演算法並沒有細分出是那一種中文內碼, 其優點是非常簡單且處理快速, 但也有以下需要加強之處 :

  • "非雙位元組"的中文內碼 (例如三位元組甚或四位元組的中文內碼) 。
  • 若字串或文章中含有第 8 bit 為 1 但卻不是中文碼的位元組時。

不過以上的情況就目前而言實在非常少見, 故並不會對 DBMaker 造成影響。

DBMaker 的中文能力

我們根據以下幾點來說明DBMaker的中文能力。

  • 識別字
  • DBMaker 的識別字 (Identifier) , 例如 database name, table name, column name 等等, 只要以雙引號括起來, 均可以使用中文。例如 :

       Create db "人事庫";
       Create table"員工"("姓名" char(8), "地址" char(100));
       Insert into "員工"values ("林大同", "北市長春路一號");
      
  • 資料儲存 / 處理
  • 如上所述, 處理中英文的關鍵在於第八個位元。有些英文的應用程式或使用環境, 一遇到第八個位元為 1 的碼時, 會自動跳過, 或發出錯誤訊息, 或自動將第八個位元轉為 0。這樣的處理方式顯然中文環境中是不適用的。而 DBMaker 完全沒有這樣的問題。即使資料型態為 char, varchar, 或 long varchar, DBMaker 在儲存或處理這些資料的過程中都不會任意更動第八個位元。 

  • 排序
  • 一般而言, 中文對於排序 (sorting) 並不會造成問題, 因為中文的排序乃直接以內碼來排序。DBMaker 在這方面當然也沒有問題。 

  • 中文顯示
  • 中文顯示可以說是中文環境中最大的問題所在。例如顯示中英文混雜的字串, 或是換行時如何避免切斷一個中文字等等。由於顯示是由前端之應用工具 ( tool ) 或應用程式 ( Application ) 所負責, DBMaker 只負責將資料正確無誤地傳送至前端工具或程式, 再由前端工具或程式將資料經由顯示條件將中文正確無誤的呈現出來。

    因此, 真正會影響中文顯示的是使用者端的作業系統, 開發工具, 以及其應用程式。由於 DBMaker 目前並不提供專屬的前端開發工具, 而是利用市面上所有支援 ODBC 的前端開發工具, 如 VB, Delphi, VC, PowerBuilder 等, 所以只要這些前端開發工具在其所支援的中文平台 ( platform ) 如 Microsoft Windows95, NT 等上可以正確無誤地顯示中文即可。根據我們的經驗, 使用 VB, Delphi, VC 等工具配合後端DBMaker 資料庫在中文顯示上不會有任何問題。

  • 內碼轉換

在較複雜的中文環境中由於前端中文作業系統或應用工具 ( 程式 ) 使用不同的中文字碼,為了使中文資料能作資訊的整合與互通, 在最有效的作業環境下可能需要作線上 ( on-line ) 的中文內碼轉換。例如下圖的環境:

client 1 使用電信碼, 而 client 2 使用 BIG-5 碼。若無任何內碼轉換, 則由 client 1 新增的資料是以電信碼儲存在資料庫中, 而由 client 2 新增的資料則是以 BIG-5 碼儲存在資料庫中。若 client 1 選擇存取到 BIG-5 碼資料, 或 client 2 使用到電信碼資料, 那麼,由於字碼之對應不同,而會造成字型與字碼牛頭不對馬嘴的現象, 在資料顯示上將會不知所云,或者甚至無法顯示。

因此,比較好的解決辦法是讓資料庫中所儲存的中文資料的中文碼一致, 如選擇最通用的 BIG-5 碼,然後凡是非 BIG-5 碼的前端系統均需將資料轉換為 BIG-5 碼後再存入資料庫中。同理, 這些前端系統必須先將從資料庫中取得的 BIG-5 資料轉換成自己的中文碼才能顯示。如下圖:

理論上內碼轉換層可以實作 (implement) 在資料庫系統(Database Server) 核心程式中, 或者在前端介面程式中 (例如 ODBC driver 內), 當然也可以由應用工具或應用程式自己轉換。在這些方法中,比較理想的方式是將此中文內碼轉換模組實作在資料庫系統核心程式中。以如下之資料查詢指令為例:

Select * from DB1:Table1, DB2:Table2 where Table1.name = Table2.name;
//*不同資料庫內的 table 作 join 的例子*//   
  

假設 DB1 與 DB2 儲存的資料使用不同的中文碼, 則這個例子只有將內碼轉換層實作在資料庫核心程式內才能正確無誤地執行。當然, 此一實作方式雖然功能較強, 卻是最複雜且最難實作的。

目前 DBMaker 並沒有內碼轉換的功能, 所以若真有此需求, 只能由應用程式自己轉換, 但我們並不排除未來會將內碼轉換功能實作進DBMaker 的可能性。

  • 字串處理
  • 前述提及中文字碼以 2 個位元組來組合而成,其第一個位元組之第八個位元為 1, 與 ASCII 字碼 (第八個位元為 0 ) 不同。但其第二個位元組為任意字碼因此,若不作適當的辨識處理,則發生錯誤的可能性將會很大。

    舉例來說, 有些資料庫系統內建的函數會對字碼作相對的處理, 例如 UpperCase (將字串中英文小寫字碼轉成大寫) 與 LowerCase (字碼轉成小寫)。看看下面這個例子:

    Select ucase(book_name) from book;    

    若 book 中均為英文書, 則此查詢指令將可得到正確資料。但若中英文書混雜, 此查詢指令在處理中文書名時若不做適當的辨識, 則會將原本屬於中文的碼 (第二個位元組) 當作 ASCII 而將之轉成大寫, 造成錯誤。

    DBMaker 的內建函數在處理字串時, 已經考慮到類似問題, 會自動判斷中英文,並正確執行相對工作。 

  • 資料比對與全文檢索

DBMaker在資料比對 (pattern matching) 以及全文檢索 (full text searching)方面提供了 like, match, 及 contain 等功能。這些功能均具備處理中文的能力, 這是一般非中文資料庫所無法提供的。我們舉例如下 : 

  1. 比對的正確性
  2. 假設 table_1只有 column_1這個欄位, 且有三筆資料如下:

    "aab"
    "a中b"
    "abc" 
        

    以如下之查詢指令查詢相關資料:

    select column_1 from table1 where column_1 like 'a_b';      

    若資料庫系統無法辨識中文,則上述指令所得的結果將只有 "aab" 這一筆資料, 主要的原因是在比對過程資料庫系統是以英文之單一位元組作比對。

    但是對於中文化環境的字碼意義應是以一個字來處理才對, 因此, 中文化的資料庫應該查詢比對出 2 筆資料 "aab" 和 "a 中 b"。DBMaker 正是一個標準的中文化資料庫。

  3. 間隔字元處理
  4. 間隔字元, 如空白, Tab, 換行, 換頁等等, 常會夾雜在中文字串中。這些間隔字元在中文字串中是無意義的, 但卻會造成比對上的困難。例如:

    select news from article where news match '林大同'; 

    凡是含

    '林大同' ,  
    '林(空格)大(空格)同' ,
    '林 (換行)
    大同' 

    等字串的文章均會被DBMaker 查詢比對出來。

結論

作為國人獨力開發的第一套資料庫管理系統, DBMaker 的確具備與眾不同的中文能力。而我們要強調的是, DBMaker 還在不斷進步中, 我們擁有 DBMaker 每一行原始程式, 並且完全掌控, 所以能作到最佳的可塑性, 機動性, 以至於擁有最強大的支援能力。

Copyright 2002 SYSCOM Computer Engineering Co. All rights reserved.