SQL Server 2005 中的國際功能(1)

 

簡介

Microsoft SQL Server 2005 是在 SQL Server 2000 中引入的 Unicode 和 XML 支持的基礎上構建,並通過 SQL Server Management Studio 和 Business Intelligence Development Studio 添加了一組全新的、功能強大的開發和查詢工具。可靠的多語言功能使 SQL Server 2005 在支持國際操作和環境方面成爲引人注目的數據庫產品和應用程序平臺。

本白皮書在全局上下文中提供了對這些功能的概述。它列出了與國際和多語言要求有關的功能,並說明了設計決策能夠對項目的衆多方面產生怎樣的影響。

注意 本文使用以下國際字體來提供某些國際字符的示例:Arial Unicode MS、Latha、Mangal、PmingLiu、Gulim、SimSun 和 MS-Mincho。不安裝這些字體不會對本文的有效性產生嚴重影響。

SQL Server 2005 中的 Unicode 支持

Unicode 支持是 SQL Server 2005 中多語言支持的基礎。

Unicode 是由 Unicode Consortium(一個提倡爲所有語言使用單一字符集的組織)創立的一項標準。SQL Server 2005 支持 Unicode 標準 3.2 版。Unicode 標準的 3.01 版與 ISO-10646(一項與 Unicode 中的所有碼位均相符的國際標準)完全相同。

Unicode 的工作方式是,爲每個字符提供一個唯一的碼位,該碼位與平臺、程序或語言無關。支持 Unicode 的程序可以處理任何語言的數據。因爲其設計宗旨是涵蓋世界上所有語言的所有字符,所以不需要讓不同的代碼頁來處理不同的字符集。

因爲所有 Unicode 系統都統一使用相同的位模式來表示所有字符,所以從一個系統轉到另一個系統時,不會出現字符轉換不正確的問題。

管理國際數據庫中的字符數據的最簡單方法是始終使用 Unicode nchar、nvarchar 和 nvarchar(max) 數據類型,而不使用它們對應的非 Unicode 數據類型:char、varchar 和 text。這樣,客戶端與所有其他客戶端所看到的數據中的字符將是相同的。如果所有使用國際數據庫的應用程序還使用 Unicode 變量來代替非 Unicode 變量,則不需要在系統中的任何位置執行字符轉換。

注意 未來版本的 Microsoft SQL Server 中將刪除 ntext 數據類型。

Unicode 碼位及它們所代表的字符與用於可視呈現的“字形”是分開的。ISO 標準 (ISO/IEC 9541-1) 將字形定義爲“與具體設計無關的可識別抽象圖形符號”。因此,一個字符不必總是由相同的字形乃至唯一的字形來表示。所選擇的字體決定將使用什麼字形來表示特定碼位或一系列碼位。

編碼

Unicode 將碼位映射到字符,但實際上並不指定數據在內存、數據庫或網頁中的表示方式。這便是 Unicode 數據編碼發揮作用的地方。有許多不同的 Unicode 編碼。多半選擇一種 Unicode 數據類型即可,不必爲這些細節操心;不過,在以下情況下了解編碼有重要意義:

應對可能以不同方式對 Unicode 進行編碼的應用程序時

向其他平臺(非 Microsoft Windows)或 Web 服務器發送數據時

導入其他編碼的數據或將數據導出爲其他編碼時

Unicode 標準定義了其單一字符集的多種編碼:UTF-7、UTF-8、UTF-16 和 UTF-32。本部分對這些常見的編碼進行說明:

UCS-2

UTF-16

UTF-8

SQL Server 通常以 UCS-2 編碼方案存儲 Unicode。不過,許多客戶端以另一種編碼方案(如 UTF-8)來處理 Unicode。這種情況在基於 Web 的應用程序中經常出現。在 Microsoft Visual Basic 應用程序中,字符串以 UCS-2 編碼方案來處理。因此,不需要顯式地指定 Visual Basic 應用程序與 SQL Server 實例之間的編碼方案轉換。

SQL Server 2005 使用 Unicode (UTF-16) 來對 XML 數據進行編碼。類型爲 xml 的列中的數據以內部格式存儲爲二進制大型對象 (BLOB),以支持 XML 模型特徵,如文檔順序和遞歸結構。因此,從服務器檢索的 XML 數據會以 UTF-16 格式輸出;如果想要爲檢索的數據使用其他編碼,則應用程序必須對所檢索的 UTF-16 數據執行必要的轉換。

使用 UTF-16 編碼是因爲它可以處理 2 字節或 4 字節字符,並且處理是依照面向字節的協議進行的。這些特性使得 UTF-16 非常適合於遍歷使用不同編碼和字節排序系統的不同計算機。因爲 XML 數據通常在網絡上得到廣泛共享,所以在數據庫中及在將 XML 數據導出到客戶端時保持默認的 UTF-16 存儲格式是有意義的。

UCS-2

UCS-2 是 UTF-16 的前身。UCS-2 與 UTF-16 的不同之處是,UCS-2 是一種固定長度編碼,它以 16 位值(2 個字節)表示所有字符,因此不支持補充字符。UCS-2 常與 UTF-16 發生混淆,UTF-16 用於在內部表示 Microsoft Windows 操作系統(Windows NT、Windows 2000、Windows XP 和 Windows CE)中的文本,但 UCS-2 受到的限制更多。

在 Microsoft SQL Server 2000 和 Microsoft SQL Server 2005 中以 Unicode 存儲的信息使用 UCS-2 編碼,無論使用的是哪個字符,該編碼都將每個字符存儲爲兩個字節。因此,對拉丁語字母“A”的處理方式與對西里爾文字母 Sha ())、希伯來語字母 Lamed (ì)、泰米爾語字母 Rra (?) 或日語平假名字母 E (‚¦) 的處理方式是相同的。每個字母都有一個唯一的碼位(對於上述字母,碼位分別爲 U+0041、U+0248、U+05DC、U+0BB1 和 U+3048,每個四位十六進制數表示 UCS-2 使用的那兩個字節)。

因爲 UCS-2 只考慮了 65,536 個不同碼位的編碼,其本身無法處理補充字符,只能將補充字符視爲未定義的 Unicode 代理項字符,這些字符組對後定義補充字符。不過,SQL Server 可以存儲補充字符而不會有字符丟失或損壞的風險。通過創建自定義 CLR 函數,可以擴展 SQL Server 處理代理項對的能力。有關處理代理項對和補充字符的詳細信息,請參閱本文後面的“補充字符和代理項對”部分。

注意 補充字符定義爲“具有補充碼位的 Unicode 編碼字符”。補充碼位的範圍在 U+10000 和 U+10FFFF 之間。

UTF-8

UTF-8 是一種旨在以與計算機上的字節排序無關的方式來處理 Unicode 數據的編碼方案。在處理 ASCII 及其他要求使用 8 位編碼的面向字節的系統(例如,必須覆蓋大量使用不同編碼、不同字節順序和不同語言的計算機的郵件服務器)時,UTF-8 會有幫助。儘管 SQL Server 2005 不以 UTF-8 格式存儲數據,但它仍支持使用 UTF-8 來處理可擴展標記語言 (XML) 數據。有關詳細信息,請參閱本文的 SQL Server 2005 中的 XML 支持部分。

其他數據庫系統(例如,Oracle 和 Sybase SQL Server)通過使用 UTF-8 存儲來支持 Unicode。視服務器的實現方式而定,從技術上講實現數據庫引擎可能比較容易,因爲服務器上的現有文本管理代碼在一次處理一個字節的數據時並不要求進行重大更改。不過,在 Windows 環境中,UTF-8 存儲有幾個缺點:

組件對象模型 (COM) 僅在其 API 和接口中支持 UTF-16/UCS-2。因此,如果數據以 UTF-8 格式存儲,必須始終進行轉換。僅在使用 COM 時會出現此問題;SQL Server 數據庫引擎通常不會調用 COM 接口。

Windows XP 和 Windows Server 2003 的內核均採用 Unicode。UTF-16 是 Windows 2000、Windows XP 和 Windows Server 2003 的標準編碼。不過,Windows 2000、Windows XP 和 Windows Server 2003 都可以識別 UTF-8。因此,在數據庫中使用 UTF-8 存儲格式需要進行許多額外的轉換。通常,轉換所需的額外資源不會影響 SQL Server 數據庫引擎,但可能會影響許多客戶端操作。

執行許多字符串操作時,UTF-8 的速度可能都會較慢。排序、比較及幾乎任何字符串操作的速度可能都會下降,因爲字符的寬度不固定。

UTF-8 往往需要 2 個以上的字節,並且增加的大小會佔用更多的磁盤和內存空間。

儘管有這些缺點,但考慮到 XML 已成爲一項重要的 Internet 通信標準這一事實,您可能希望考慮將默認編碼設置爲 UTF-8。

注意 早期版本的 Oracle 和 Java 也使用 UCS-2,它們無法識別代理項。Oracle Corporation 在 Oracle 7 中開始支持將 Unicode 作爲數據庫字符集。Oracle 目前支持兩種 Unicode 數據存儲方法:(1) UTF-8 作爲 CHAR 和 VARCHAR2 字符數據類型以及所有 SQL 名稱和文字的編碼;(2) UTF-16 用於 NCHAR、NVARCHAR 和 NCLOB Unicode 數據類型的存儲。Oracle 允許同時使用這兩種方法。

UTF-16

UTF-16 是 Microsoft 的編碼標準,在 Windows 操作系統中 UTF-16 是一個擴展,其設計用途是處理附加的 1,048,576 個字符。對代理項範圍的需要甚至在 Unicode 2.0 發佈之前就已意識到了,因爲事實清楚地表明,僅使用 65,536 個字符無法實現 Unicode 的用單一碼位表示每種語言的每個字符的目標。例如,某些語言(例如,中文)至少需要那樣多的字符才能對歷史和文學表意文字等字符進行編碼,這些字符儘管很少使用,但對出版和學術有着重要意義。下一部分提供了有關代理項範圍的詳細信息。

UTF-16 與 UCS-2 類似,也使用 little endian 字節順序,在 Windows 上執行的任何操作都遵循該順序。Little endian(與 big endian 相對)意味着低位字節存儲在內存中的最低地址處。在操作系統級別字節的排序有重要意義。SQL Server 以及運行在 Windows 平臺上的其他應用程序都使用 little endian 字節順序。因此,0x1234 這樣的十六進制詞語以 0x34 0x12 形式存儲在內存中。在某些情況下,可能需要顯式地反轉字節順序以正確地讀取字符的編碼。SQL Server Integration Services 提供了用於轉換 Unicode 文本字節順序的函數。有關詳細信息,請參閱本文的 SQL Server 2005 Integration Services 部分。

補充字符和代理項對

Microsoft Windows 通常使用 UTF-16 來表示字符數據。使用 16 位允許表示 65,536 個唯一字符。不過,即使是這麼多的字符也不足以涵蓋人類語言中使用的所有符號。在 UTF-16 中,某些碼位緊接着前兩個字節使用另一個碼位,以將該字符定義爲代理項範圍的一部分。

在 Unicode 標準中,有 16 個字符“平面”,具有定義多達 1,114,112 個字符的潛力。平面 0(或稱基本多語言塊 (BMP))可以表示世界上的大部分書面文字、出版中使用的字符、數學和技術符號、幾何圖形、所有 100 級 Zapf Dingbat 以及標點符號。

在 BMP 之外,大部分平面中的字符仍未定義,但可以用來表示補充字符。補充字符主要用於歷史和古典文學典籍,以協助處理中文、韓語和日語豐富文學遺產的編碼。補充字符還包括古代北歐文字以及其他具有歷史意義的文字、音樂符號等。

在 UTF-16 中,一對碼位(稱爲代理項對)用於表示主字符集 (BMP) 之外的字符。代理項區是 Unicode 中從 U+D800 到 U+DFFF 的一個範圍,其中包含 1,024 個低代理項值和 1,024 個高代理項值。高代理項(範圍 U+D800 到 U+DBFF)和低代理項(範圍 U+DC00 到 U+DFFF)相結合可以表示超過一百萬個可能的字符。

僅具有代理項對的一半將視爲無效;高代理項必須始終跟有低代理項,纔算有效。這使得代理項的檢查變爲範圍檢查,它比檢測 DBCS(雙字節字符系統)字符所需的相當複雜的規則要簡單。

儘管 UCS-2 不能識別代理項,但 SQL Server 2000 和 SQL Server 2005 都可以存儲代理項對。SQL Server 將代理項對視爲兩個未定義的 Unicode 字符而非單一字符。此類應用程序通常稱爲“代理中性”或“代理安全”,這意味着它們不具備固有的與數據進行交互的能力,但至少可以做到存儲的數據不會丟失。

作爲對照,“能夠識別代理項的”應用程序不僅可以識別代理項對,還可以處理組合字符和需要特殊處理的其他字符。編寫良好的應用程序可以檢測到分開的代理項,並且只通過幾個子例程就可以將它們重新組合。可以識別代理項的應用程序包括 Microsoft Word 和 Internet Explorer 5 及更高版本。

在 SQL Server 中處理補充字符時,請記住以下幾點:

因爲代理項對被視爲兩個獨立的 Unicode 碼位,所以 nvarchar(n) 的大小必須是 2,以容納單一補充字符(換言之,代理項對所需的空間)。

不支持在元數據(例如,數據庫對象的名稱)中使用補充字符。一般來說,元數據中使用的文本必須符合標識符的規則。

標準字符串操作不能識別補充字符。SUBSTRING(nvarchar(2),1,1) 之類的操作僅返回補充字符代理項對的高代理項。LEN 函數爲遇到的每個補充字符返回兩個字符的計數:一個計數對應高代理項,一個計數對應低代理項。不過,可以創建能夠識別補充字符的自定義函數。

對補充字符的排序和搜索行爲可能會隨排序規則的不同而發生變化。在新的 90_and BIN2 排序規則中,可以正確地對補充字符進行比較,而在早期排序規則和標準 Windows 排序規則中,所有補充字符的比較都視同所有其他補充字符的比較。例如,默認的日語和朝鮮語排序規則不處理補充字符,而 Japanese_90 和 Korean_90 則會進行處理。

 

組合字符

“組合字符”是與其他字符一起使用以修改其外觀或含義的字符。組合的字符會形成單一字形。例如,歐洲語言中使用的音調符號便是組合字符,可以作爲字符加音調符號的形式或預構成字符的形式出現。

在 .NET Framework 中,將組合字符的順序視爲文本元素,即顯示爲單個字符的文本單元。文本元素有別於排序元素。例如,在某些排序規則中,字母“CH”不是組合字符;它們是兩個獨立的文本元素,但可以將它們視爲一個排序元素。

注意 SQL 函數的做法有所不同,它通常將組合字符與補充字符一視同仁:它們將組合字符作爲兩個獨立的 Unicode 碼位進行處理。

組合字符映射到排序元素的方式取決於 Unicode 標準和排序規則這兩者。某些組合字符始終被視爲等同於它們的變體形式,無論它們包括多少不同的碼位(例如,拉丁文字母加音調符號被視爲等同於包括音調符號的預構成字符),而在某些排序規則中,可以根據音調符號是否存在以不同方式對字符串進行排序或比較。

組合字符最初是在 Unicode 2.0 中定義的。有關詳細信息,請參閱論述“特殊區域和格式字符”的 Unicode 4.0.1 規範部分。Unicode Consortium 還發布了專門針對組合字符及其處理的 FAQ。有關在 .NET Framework 中處理組合字符的方法的詳細信息,請參閱《.NET Framework 開發人員指南》中的標準化

對 GB18030 的支持

GB18030 (GB18030-2000) 是中華人民共和國 (PRC) 頒佈的一項針對中文字符編碼的獨立標準。它對擴展代碼頁和與 Unicode 的映射表都做了規定。官方要求從 2006 年 8 月 1 日起,在 PRC 境內銷售的所有軟件產品都必須支持此字符集。GB18030 一致性包括對支持一些以前並不支持的語言(例如,藏文、蒙文、彝文和維吾爾文)的要求。

在 GB18030 中,字符可以是 1、2 或 4 個字節。代理項對用於支持 GB18030 的 4 字節序列與 Unicode 的映射。

SQL Server 2005 通過在採用 GB18030 編碼的字符從客戶端應用程序進入服務器時對它們進行識別來提供對這些字符的支持。SQL Server 2005 會在本地對這些字符進行轉換,並將它們存儲爲 Unicode 字符。這些字符存儲在服務器中後,在對它們執行的所有後續操作中均將它們視爲 Unicode 字符。GB18030 不具有系統區域設置;它只有一個代碼頁標識符,以實現與 Unicode 之間的相互轉換。Microsoft 針對 GB18030-2000 的代碼頁標識符爲 54936。

使用 GB18030 字符時,請記住這些字符可以在排序和比較操作中使用,但如果使用的是 SQL Server 90 之前的排序規則,將只能基於這些字符的碼位而不能基於其他有語言意義的方式進行比較。因此,在 ORDER BY、GROUP BY 和 DISTINCT 等操作中使用 GB18030 字符時,尤其是在同一操作中同時包括 GB18030 字符和非 GB18030 字符時,應謹慎行事。要支持有意義的使用 GB18030 字符的字符串比較,請使用新的 SQL Server 90 排序規則版本(以添加到其名稱中的 90 後綴表示)。例如,請使用 Chinese_PRC_90 排序規則,而不使用 Chinese_PRC 排序規則。

要啓用對 GB18030 標準的支持,可以安裝一個支持軟件包,該軟件包可以從 Microsoft 產品幫助和支持門戶下載,其中包括支持 GB18030 與 Unicode 之間轉換所需的字體文件和庫。該支持軟件包是一個可以在 Windows XP 或 Windows 2000 上安裝的單一全球二進制。不過,系統必須安裝可選的東亞語言支持。Windows Vista 中包括了對 GB18030 標準的支持,其中包括針對中國少數民族語言(如藏文、蒙文、彝文和維吾爾文)的字體和鍵盤佈局。這些語言均使用中文 (PRC) 區域設置。

注意Vista 中不支持某些將 GB18030 字節轉換爲 Unicode 字符的函數,如 BytesToUnicode。在 Vista 中將 GB18030 字節轉換爲 Unicode 字符時,請使用 MultiByteToWideChar 函數。

SQL Server 2005 中的數據類型

本部分介紹 SQL Server 2005 中的新數據類型,並說明與使用 SQL Server 2005 數據類型存儲國際數據相關的問題。

非 Unicode 文本類型:char、varchar、text、varchar(max)

當處理以 char、varchar、varchar(max) 或 text 數據類型存儲的文本數據時,需要考慮的最重要限制因素是,系統只能驗證來自單一代碼頁的信息。(您可以存儲來自多代碼頁的數據,但不建議這樣做。)用於驗證和存儲數據的確切代碼頁取決於列的排序規則。如果尚未定義列級排序規則,則使用數據庫的排序規則。要確定給定列所用的代碼頁,可以使用 COLLATIONPROPERTY 函數,如以下代碼示例所示:


最後一個示例返回 0 (Unicode) 作爲印地語的代碼頁。此示例說明了一個事實,即許多語言環境(例如格魯吉亞語和印地語)都沒有代碼頁,因爲他們僅使用 Unicode 排序規則。那些排序規則不適用於使用 char、varchar 或 text 數據類型的列,並且某些排序規則不受支持。

重要信息 在 SQL Server 2005 中,使用 varchar(max) 數據類型而非 text 數據類型。未來版本的 Microsoft SQL Server 將刪除 text 數據類型。

當必須將 Unicode 數據插入到非 Unicode 列時,通過使用 WideCharToMultiByte API 和與排序規則關聯的代碼頁,會在內部將列從 Unicode 轉換成非 Unicode。如果在給定代碼頁上無法表示某字符,則用問號 (?) 替換該字符。因此,如果數據內隨機出現問號,則充分說明數據由於未指定的轉換而被破壞。這也充分說明轉換爲 Unicode 數據類型對應用程序很有好處。

如果使用排序規則不支持的非 Unicode 類型的字符串文字,則首先會使用數據庫的默認代碼頁轉換字符,該代碼頁源自數據庫的默認排序規則。

可能遇到的另一個問題是,當代碼頁中未包含希望支持的所有字符時無法存儲數據。多數情況下,Windows 會將特定代碼頁視爲“最適合”代碼頁,這意味着無法保證利用該代碼頁可以處理所有文本,它只是可以利用的最佳選擇。這種情況一個例證是阿拉伯語腳本:它支持多種語言,其中包括俾路支語、柏柏爾語、波斯語、克什米爾語、哈薩克語、吉爾吉斯語、庫爾德語、普什圖語、信德語、維吾爾語、烏爾都語以及更多語言。除 Windows 代碼頁 1256 中所定義阿拉伯語中的那些字符之外,所有這些語言還有其他字符。如果試圖在具有阿拉伯排序規則的非 Unicode 列中存儲這些額外字符,則這些字符會被轉換成問號。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章