一、varchar[(n)] 和nvarchar(n) 及使用unicode的意義
1.varchar[(n)]
長度為 n 個字節(jié)的可變長度且非 Unicode 的字符數(shù)據(jù)。n 必須是一個介于 1 和 8,000 之間的數(shù)值。存儲大小為輸入數(shù)據(jù)的字節(jié)的實際長度,而不是 n 個字節(jié)。所輸入的數(shù)據(jù)字符長度可以為零。varchar 在 SQL-92 中的同義詞為 char varying 或 character varying。
2.nvarchar(n)
包含 n 個字符的可變長度 Unicode 字符數(shù)據(jù)。n 的值必須介于 1 與 4,000 之間。字節(jié)的存儲大小是所輸入字符個數(shù)的兩倍。所輸入的數(shù)據(jù)字符長度可以為零。nvarchar 在 SQL-92 中的同義詞為 national char varying 和 national character varying。
3.什么是Unicode編碼
Unicode(統(tǒng)一碼、萬國碼、單一碼)是一種在計算機上使用的字符編碼。它為每種語言中的每個字符設(shè)定了統(tǒng)一并且唯一的二進制編碼,以滿足跨語言、跨平臺進行文本轉(zhuǎn)換、處理的要求。1990年開始研發(fā),1994年正式公布。隨著計算機工作能力的增強,Unicode也在面世以來的十多年里得到普及。
2006年6月的最新版本的 Unicode 是 2005年3月31日推出的Unicode 4.1.0 。另外,5.0 Beta已于2005年12月12日推出,以供各會員評價。
對于英文來說,ascii碼0-127就足以代碼所有字符,對于中文而言,則必須使用兩個字節(jié)(byte)來代表一個字符,具第一個字節(jié)必須大于127(所以我們有許程序判斷中文都是以ascii碼大于127作為條件) 以上用兩個字節(jié)來表示一個中文的方式,在習慣上稱為雙字節(jié)(即DBCS:Double-ByteCharacterSet),而相對之下,英文的字符碼就稱為單字節(jié)SBCS(Single-ByteCharacterSet)。 雖然雙字節(jié)(DBCS)足以解決中英文字符混合使用情況,但對于不同字符系統(tǒng)而言,必須經(jīng)過字符碼轉(zhuǎn)換,非常麻煩。例如:中英文混合情況,日文,韓文等等。 為解決這個問題,Apple,Xerox,Microsoft,IBM,Novell,Borland...很多公司聯(lián)合起來制訂了一套可以適用于全世界所有國家的字符碼,就稱為Unicode Unicode的特點是: 不管哪一國的字符碼均以兩個Byte表示,例如"A"在Unicode則是16進制41和00的組合,即4100,高位41(轉(zhuǎn)換為Ascii碼即是65=A), WindowsNT/2000以Unicode來表示字符集,例如你可以看到MSSQLServer中產(chǎn)生的SQL文件可以選擇是以Unicode來保存還是以普通格式來保存,如果你以Unicode保存,則在95/98平臺許多軟件均無法正確讀出其格式。 同時你還可以注意到95/98中API定義,許多名稱結(jié)尾是有一個A的,例如 WriteProfileStringA 而在NT/2000操作系統(tǒng)中,提供了兩套API,另外一個命令是WriteProfileStringW,以W結(jié)尾的API只適用于NT/2000。(在NT中使用以W結(jié)尾的API函數(shù)效率比A結(jié)尾的要快,因為省去了Unicode和DBCS/SBCS的轉(zhuǎn)換過程)
這樣我們經(jīng)常要用到的判斷字符串長度的函數(shù),在NT和95/98下執(zhí)行結(jié)果不同,如下:(下面代碼適合于VB,ASP)
95/98中: len("abc中國")返回7(因為每個中文作為兩個Ascii碼來看)
nt/2000中: len("abc中國")返回5(因為每個字符都作為一個Unicode來看)
二、Unicode 的編碼和實現(xiàn)
大概來說,Unicode 編碼系統(tǒng)可分為編碼方式和實現(xiàn)方式兩個層次。
1.編碼方式
Unicode 的編碼方式與 ISO 10646 的通用字元集(亦稱[通用字符集])(Universal Character Set,UCS)概念相對應(yīng),目前的用于實用的 Unicode 版本對應(yīng)于 UCS-2,使用16位的編碼空間。也就是每個字符占用2個字節(jié)。這樣理論上一共最多可以表示 216 個字符?;緷M足各種語言的使用。實際上目前版本的 Unicode 尚未填充滿這16位編碼,保留了大量空間作為特殊使用或?qū)頂U展。
上述16位 Unicode 字符構(gòu)成基本多文種平面(Basic Multilingual Plane, 簡稱 BMP)。最新(但未實際廣泛使用)的 Unicode 版本定義了16個輔助平面,兩者合起來至少需要占據(jù)21位的編碼空間,比3字節(jié)略少。但事實上輔助平面字符仍然占用4字節(jié)編碼空間,與 UCS-4 保持一致。未來版本會擴充到 ISO 10646-1 實現(xiàn)級別3,即涵蓋 UCS-4 的所有字符。UCS-4 是一個更大的尚未填充完全的31位字符集,加上恒為0的首位,共需占據(jù)32位,即4字節(jié)。理論上最多能表示 231 個字符,完全可以涵蓋一切語言所用的符號。
BMP 字符的 Unicode 編碼表示為 U+hhhh,其中每個 h 代表一個十六進制數(shù)位。與 UCS-2 編碼完全相同。對應(yīng)的4字節(jié) UCS-4 編碼后兩個字節(jié)一致,前兩個字節(jié)的所有位均為0。
2.實現(xiàn)方式
Unicode 的實現(xiàn)方式不同于編碼方式。一個字符的 Unicode 編碼是確定的。但是在實際傳輸過程中,由于不同系統(tǒng)平臺的設(shè)計不一定一致,以及出于節(jié)省空間的目的,對 Unicode 編碼的實現(xiàn)方式有所不同。Unicode 的實現(xiàn)方式稱為Unicode轉(zhuǎn)換格式(Unicode Translation Format,簡稱為 UTF)。
例如,如果一個僅包含基本7位ASCII字符的 Unicode 文件,如果每個字符都使用2字節(jié)的原 Unicode 編碼傳輸,其第一字節(jié)的8位始終為0。這就造成了比較大的浪費。對于這種情況,可以使用 UTF-8 編碼,這是一種變長編碼,它將基本7位ASCII字符仍用7位編碼表示,占用一個字節(jié)(首位補0)。而遇到與其他 Unicode 字符混合的情況,將按一定算法轉(zhuǎn)換,每個字符使用1-3個字節(jié)編碼,并利用首位為0或1進行識別。這樣對以7位ASCII字符為主的西文文檔就大大節(jié)省了編碼長度(具體方案參見UTF-8)。類似的,對未來會出現(xiàn)的需要4個字節(jié)的輔助平面字符和其他 UCS-4 擴充字符,2字節(jié)編碼的 UTF-16 也需要通過一定的算法進行轉(zhuǎn)換。
再如,如果直接使用與 Unicode 編碼一致(僅限于 BMP 字符)的 UTF-16 編碼,由于每個址 加昧肆礁鱟紙冢 贛acintosh機和PC機上對字節(jié)順序的理解是不一致的。這時同一字節(jié)流可能會被解釋為不同內(nèi)容,如編碼為 U+594E 的字符“奎”同編碼為 U+4E59 的“乙”就可能發(fā)生混淆。于是在 UTF-16 編碼實現(xiàn)方式中使用了大尾序(big-endian)、小尾序(little-endian)的概念,以及BOM(Byte Order Mark)解決方案。(具體方案參見UTF-16)
此外 Unicode 的實現(xiàn)方式還包括 UTF-7、Punycode、CESU-8、SCSU、UTF-32等,這些實現(xiàn)方式有些僅在一定的國家和地區(qū)使用,有些則屬于未來的規(guī)劃方式。目前通用的實現(xiàn)方式是 UTF-16小尾序(BOM)、UTF-16大尾序(BOM)和 UTF-8。在微軟公司W(wǎng)indows XP操作系統(tǒng)附帶的記事本中,“另存為”對話框可以選擇的四種編碼方式除去非 Unicode 編碼的 ANSI 外,其余三種“Unicode”、“Unicode big endian”和“UTF-8”即分別對應(yīng)這三種實現(xiàn)方式。
目前輔助平面的工作主要集中在第二和第三平面的中日韓統(tǒng)一表意文字中,因此包括GBK、GB18030、Big5等簡體中文、正體中文、日文、韓語以及越南字喃的各種編碼與 Unicode 的協(xié)調(diào)性被重點關(guān)注??紤]到 Unicode 最終要涵蓋所有的字符,從某種意義而言,這些編碼方式也可視作 Unicode 的出現(xiàn)于其之前的既成事實的實現(xiàn)方式,如同ASCII及其擴展Latin-1一樣,后兩者的字符在16位 Unicode 編碼空間中的編碼第一字節(jié)各位全為0,第二字節(jié)編碼與原編碼完全一致。但上述東亞語言編碼與 Unicode 編碼的對應(yīng)關(guān)系要復(fù)雜得多。
三、非 Unicode 環(huán)境
在非 Unicode 環(huán)境下,由于不同國家和地區(qū)采用的字符集不一致,很可能出現(xiàn)無法正常顯示所有字符的情況。微軟公司使用了代碼頁(Codepage)轉(zhuǎn)換表的技術(shù)來過渡性的部分解決這一問題,即通過指定的轉(zhuǎn)換表將非 Unicode 的字符編碼轉(zhuǎn)換為同一字符對應(yīng)的系統(tǒng)內(nèi)部使用的 Unicode 編碼??梢栽?#8220;語言與區(qū)域設(shè)置”中選擇一個代碼頁作為非 Unicode 編碼所采用的默認編碼方式,如936為簡體中文GBK,950為正體中文Big5(皆指PC上使用的)。在這種情況下,一些非英語的歐洲語言編寫的軟件和文檔很可能出現(xiàn)亂碼。而將代碼頁設(shè)置為相應(yīng)語言中文處理又會出現(xiàn)問題,這一情況無法避免。從根本上說,完全采用統(tǒng)一編碼才是解決之道,但目前上無法做到這一點。 代碼頁技術(shù)現(xiàn)在廣泛為各種平臺所采用。UTF-7 的代碼頁是65000,UTF-8 的代碼頁是65001。
|