SQL Server 2005 中的国际功能(1)

来源:互联网 发布:mysql修改密码 编辑:程序博客网 时间:2024/05/17 06:42
 

简介

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 函数,如以下代码示例所示:

SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage')936SELECT COLLATIONPROPERTY('Latin1_General_CI_AI', 'CodePage')1252SELECT COLLATIONPROPERTY('Hindi_CI_AI_WS', 'CodePage')0

最后一个示例返回 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 列中存储这些额外字符,则这些字符会被转换成问号。