Collation and Unicode Support

SQL Server 中的排序规则可为您的数据提供排序规则、区分大小写属性和区分重音属性。 与诸如 charvarchar 等字符数据类型一起使用的排序规则规定可表示该数据类型的代码页和对应字符。 无论是安装SQL Server的新实例、还原数据库备份,还是将服务器连接到客户端数据库,都必须了解将要处理的数据的区域设置要求、排序顺序以及大小写和重音敏感度。 若要列出 SQL Server 实例上可用的排序规则,请参阅 sys.fn_helpcollations (Transact-SQL)

在为您的服务器、数据库、列或表达式选择排序规则时,也在向您的数据分配某些特征,这些特征将会影响数据库中许多操作的结果。 例如,使用 ORDER BY 构造查询时,结果集的排序顺序可能取决于应用于该数据库的排序规则或 COLLATE 子句中在查询的表达式级别规定的排序规则。

若要在 SQL Server 中充分利用排序规则支持,必须了解本主题中定义的术语,以及它们与数据特征的关系。

排序规则

排序规则指定表示数据集中每个字符的位模式。 排序规则还确定数据的排序和比较规则。 SQL Server 支持在单个数据库中存储具有不同排序规则的对象。 对于非 Unicode 列,排序规则设置指定数据的代码页以及可以表示哪些字符。 必须将在非 Unicode 列间移动的数据从源代码页转换到目标代码页。

当 Transact-SQL 语句在具有不同排序规则设置的不同数据库上下文中运行时,其运行结果可能会不同。 如果可能,请为您的组织使用标准化排序规则。 这样就不必显式指定每个字符或 Unicode 表达式中的排序规则。 如果必须使用具有不同排序规则和代码页设置的对象,请对查询进行编码,以考虑排序规则的优先顺序规则。 有关详细信息,请参阅 排序规则优先顺序 (Transact-SQL)

与排序规则关联的选项是区分大小写、区分重音、区分假名以及区分全半角。 指定这些选项的方法是将它们追加到排序规则名称。 例如,排序规则 Japanese_Bushu_Kakusu_100_CS_AS_KS_WS 区分大小写、区分重音、区分假名以及区分全半角。 下表描述了与这些选项关联的行为。

选项 说明
区分大小写 (_CS) 区分大写字母和小写字母。 如果选择此项,排序时小写字母将在其对应的大写字母之前。 如果不选择此选项,则排序规则将不区分大小写。 即 SQL Server 在排序时将大写字母和小写字母视为相同。 通过指定 _CI,可以显式选择不区分大小写。
区分重音 (_AS) 区分重音字符和非重音字符。 例如,“a”和“ấ”视为不同字符。 如果未选择此选项,则排序规则将不区分重音。 即 SQL Server 在排序时将字母的重音形式和非重音形式视为相同。 通过指定 _AI,可以显式选择不区分重音。
区分假名 (_KS) 区分日语中的两种假名字符类型:平假名和片假名。 如果未选择此选项,则排序规则将不区分假名。 即 SQL Server 在排序时将平假名字符和片假名字符视为相同。 省略此选项是指定不区分假名的唯一方法。
区分全半角 (_WS) 区分全角字符和半角字符。 如果未选择此选项,SQL Server 在排序时将把同一字符的全角和半角形式视为相同。 省略此选项是指定不区分全半角的唯一方法。

SQL Server 支持以下排序规则集:

Windows 排序规则
Windows 排序规则根据关联的 Windows 系统区域设置来定义字符数据的存储规则。 在 Windows 排序规则中,使用与 Unicode 数据相同的算法实现非 Unicode 数据的比较。 Windows 基本排序规则指定应用字典排序时所用的字母表或语言,以及用于存储非 Unicode 字符数据的代码页。 Unicode 排序和非 Unicode 排序都与特定 Windows 版本中的字符串比较相兼容。 这提供了SQL Server中数据类型的一致性,还允许开发人员使用SQL Server使用的相同规则对其应用程序中的字符串进行排序。 有关详细信息,请参阅 Windows 排序规则名称 (Transact-SQL)

二进制排序规则
二进制排序规则基于区域设置和数据类型定义的编码值顺序来对数据进行排序。 它们是区分大小写的。 SQL Server 中的二进制排序规则定义将使用的区域设置和 ANSI 代码页。 这将强制使用二进制排序顺序。 由于它们相对简单,因此二进制排序规则有助于提高应用程序性能。 对于非 Unicode 数据类型,数据比较将基于 ANSI 代码页中定义的码位。 对于 Unicode 数据类型,数据比较将基于 Unicode 码位。 对于 Unicode 数据类型的二进制排序规则,数据排序将不考虑区域设置。 例如,对 Unicode 数据应用 Latin_1_General_BIN 和 Japanese_BIN,会得到完全相同的排序结果。

SQL Server中有两种类型的二进制排序规则:旧BIN排序规则和新BIN2排序规则。 在 BIN2 排序规则中,所有字符根据其码位排序。 在 BIN 排序规则中,仅首字符按照码位排序,其余字符根据其字节值排序。 (由于 Intel 平台是一个 little endian 体系结构,因此 Unicode 码字符始终以字节对调的形式存储。)

SQL Server 排序规则
SQL Server 排序规则 (SQL_*) 提供与 SQL Server 早期版本兼容的排序顺序。 非 Unicode 数据的字典排序规则与 Windows 操作系统提供的任何排序例程都不兼容。 但是,Unicode 数据的排序与特定版本的 Windows 排序规则兼容。 由于SQL Server排序规则对非 Unicode 和 Unicode 数据使用不同的比较规则,因此,对于相同数据的比较,将看到不同的结果,具体取决于基础数据类型。 有关详细信息,请参阅 SQL Server 排序规则名称 (Transact-SQL)

注意

升级 SQL Server 的英语实例时,可以指定SQL Server排序规则 (SQL_*) ,以便与现有 SQL Server 实例兼容。 由于 SQL Server 实例的默认排序规则是在安装过程中定义的,因此请确保在满足以下条件时仔细指定排序规则设置:

  • 应用程序代码依赖早期 SQL Server 排序规则的行为。
  • 必须存储反映多种语言的字符数据。

支持在 SQL Server实例的下列级别设置排序规则:

服务器级排序规则
默认服务器排序规则在SQL Server设置期间设置,并且也成为系统数据库和所有用户数据库的默认排序规则。 请注意,在设置SQL Server期间,无法选择仅限 Unicode 的排序规则,因为它们不支持作为服务器级排序规则。

除了导出所有数据库对象和数据、重新生成 master 数据库和导入所有数据库对象和数据以外,一旦为服务器分配了某一排序规则后,就无法更改该排序规则。 可以在创建新数据库或数据库列时指定所需的排序规则,而不是更改 SQL Server 实例的默认排序规则。

数据库级排序规则
创建或修改数据库时,您可使用 CREATE DATABASE 或 ALTER DATABASE 语句的 COLLATE 子句指定默认数据库排序规则。 如果未指定排序规则,将为该数据库分配服务器排序规则。

除了更改服务器的排序规则外,无法更改系统数据库的排序规则。

数据库排序规则将应用于数据库中的所有元数据,并且是所有字符串列、临时对象、变量名称和数据库中使用的任何其他字符串的默认排序规则。 当更改用户数据库的排序规则时,如果在数据库访问临时表中进行查询,则可能出现排序规则冲突。 临时表始终存储在 tempdb 系统数据库中,该数据库将使用实例的排序规则。 如果排序规则导致计算字符数据时出现冲突,则比较用户数据库和 tempdb 之间的字符数据的查询可能会失败。 您可以通过在查询中指定 COLLATE 子句来解决此问题。 有关详细信息,请参阅排序规则 (Transact-SQL)

列级排序规则
当您创建或更改表时,可使用 COLLATE 子句指定每个字符串列的排序规则。 如果未指定排序规则,则为该列分配数据库的默认排序规则。

表达式级排序规则
表达式级排序规则在语句运行时设置,并且影响结果集的返回方式。 这可以使 ORDER BY 排序结果特定于区域设置。 使用如下的 COLLATE 子句可以实现表达式级排序规则:

SELECT name FROM customer ORDER BY name COLLATE Latin1_General_CS_AI;  

Locale

区域设置是与位置或区域性相关联的一组信息。 它可以包括所用语言的名称和标识符、用于书写该语言的文字以及文化习俗。 排序规则可以与一个或多个区域设置相关联。 有关详细信息,请参阅 Microsoft 分配的区域设置 ID

代码页

代码页是给定脚本的有序字符集,其中数值索引(即码位值)与每个字符相关联。 Windows 代码页通常被称为“字符集”。 代码页用于支持不同的 Windows 系统区域设置所使用的字符集和键盘布局。

排序顺序

排序顺序指定数据值的排序方式。 它影响数据比较的结果。 数据的排序通过使用排序规则而实现,且可使用索引对排序进行优化。

Unicode 支持

Unicode 是一种将码位映射到字符的标准。 由于它旨在涵盖全球所有语言的所有字符,因此,无需使用不同代码页来处理不同字符集。 如果存储的字符数据反映多种语言,则应始终使用 Unicode 数据类型(ncharnvarcharntext),而不要使用非 Unicode 数据类型(charvarchartext)。

非 Unicode 数据类型有明显的局限性, 这是因为非 Unicode 计算机只能使用单个代码页。 通过使用 Unicode 您可能会体验到性能提升,因为需要较少的代码页转换。 必须在数据库级、列级或表达式级单独选择 Unicode 排序规则,因为在服务器级不支持 Unicode 排序规则。

客户端使用的代码页由操作系统设置确定。 若要在 Windows 操作系统上设置客户端代码页,请使用“控制面板”中的 “区域设置”

在将数据从服务器移到客户端时,服务器排序规则可能无法由旧版本的客户端驱动程序识别。 将数据从 Unicode 服务器移到非 Unicode 客户端时,可能会出现此情况。 最好升级客户端操作系统,以使基础系统排序规则得以升级。 如果客户端上安装了数据库客户端软件,则可以考虑对数据库客户端软件应用服务更新。

还可以尝试针对服务器上的数据使用另一个排序规则。 选择一个将映射到客户端上的代码页的排序规则。

若要使用 SQL Server 2019 (15.x) 中提供的 UTF-16 排序规则,可以选择一个补充字符_SC排序规则, (Windows 排序规则仅) ,以改善某些 Unicode 字符的搜索和排序。

若要评估与使用 Unicode 或非 Unicode 数据类型相关的问题,请测试您的具体方案以确定您所在环境下的性能差异大小。 最好对整个组织中的系统所使用的排序规则进行标准化,并尽可能部署 Unicode 服务器和客户端。

在许多情况下,SQL Server将与其他服务器或客户端交互,组织可能会在应用程序和服务器实例之间使用多个数据访问标准。 SQL Server 客户端是两种主要类型之一:

  • 使用 OLE DB 和开放式数据库连接 (ODBC) 3.7 版或更高版本的Unicode 客户端

  • 使用 DB-Library 和 ODBC 3.6 版或更低版本的非 Unicode 客户端

下表提供有关以 Unicode 和非 Unicode 服务器的各种组合使用多语言数据的信息。

服务器 Client 优点或局限性
Unicode Unicode 因为 Unicode 数据将在整个系统中使用,所以此方案可提供最佳的性能并可保护检索到的数据免受破坏。 ActiveX 数据对象 (ADO)、OLE DB 和 ODBC 3.7 版或更高版本都采用这样的配置。
Unicode 非 Unicode 在此方案中,尤其是在运行较新操作系统的服务器与运行较旧版本 SQL Server 的客户端或较旧操作系统之间的连接时,将数据移动到客户端计算机时可能存在限制或错误。 服务器上的 Unicode 数据会尝试映射到非 Unicode 客户端的对应代码页,以转换数据。
非 Unicode Unicode 该方案对使用多语言数据不是理想配置。 在此方案下不能向非 Unicode 服务器写入 Unicode 数据。 在向服务器的代码页之外的服务器发送数据时,很可能会发生问题。
非 Unicode 非 Unicode 这是对多语言数据有极大局限性的方案。 您只可使用一个代码页。

增补字符

SQL Server提供和 等ncharnvarchar数据类型来存储 Unicode 数据。 这些数据类型使用名为 UTF-16的格式对文本进行编码。 Unicode 协会为每个字符分配一个唯一码位,码位是一个介于 0x0000 和 0x10FFFF 之间的值。 最常用字符的码位值在内存和磁盘上的 16 位字的范围内,但码位值大于 0xFFFF 的字符需要使用两个连续的 16 位字。 这些字符称为“增补字符” ,两个连续的 16 位字称为“代理项对”

如果使用增补字符:

  • 只有在 90 版本或更高版本的排序规则中才可以将增补字符用于排序和比较操作。

  • 所有 _100 级排序规则均支持使用增补字符进行语言排序。

  • 不支持将增补字符用在元数据(如数据库对象的名称)中。

  • SQL Server 2012 中引入了一个新的补充字符系列, (SC) 排序规则可用于数据类型 ncharnvarcharsql_variant。 例如: Latin1_General_100_CI_AS_SCJapanese_Bushu_Kakusu_100_CI_AS_SC(如果使用日语排序规则)。

    SC 标志可应用于:

    • 90 版本 Windows 排序规则

    • 100 版本 Windows 排序规则

    SC 标志不能应用于:

    • 80 版本非版本化 Windows 排序规则

    • BIN 或 BIN2 二进制排序规则

    • SQL* 排序规则

下表比较了在使用具有和没有 SC 排序规则的增补字符时某些字符串函数和字符串运算符的行为。

字符串函数或运算符 具有 SC 排序规则 没有 SC 排序规则
CHARINDEX

LEN

PATINDEX
UTF-16 代理项对作为单个码位计数。 UTF-16 代理项对作为两个码位计数。
LEFT

REPLACE

REVERSE

RIGHT

SUBSTRING

STUFF
这些函数会将每个代理项对作为单个码位处理并按预期方式工作。 这些函数可能拆分任意代理项对并导致意外的结果。
NCHAR 返回对应于 0 到 0x10FFFF 范围内指定的 Unicode 码位值的字符。 如果指定的值位于 0 到 0xFFFF 范围内,则返回一个字符。 对于较高的值,则返回相应的代理项。 对于高于 0xFFFF 的值,将返回 NULL 而非相应的代理项。
UNICODE 返回 0 到 0x10FFFF 范围内的一个 UTF-16 码位。 返回 0 到 0xFFFF 范围内的一个 UCS-2 码位。
匹配一个通配符

通配符 - 无需匹配的字符
增补字符支持所有通配符操作。 增补字符不支持这些通配符操作。 支持其他通配符运算符。

GB18030 支持

GB18030 是在中华人民共和国用于对中文字符进行编码的一个单独标准。 在 GB18030 中,字符长度可以是 1 个字节、2 个字节或 4 个字节。 SQL Server 通过对从客户端应用程序进入服务器的 GB18030 编码字符进行确认,然后在本机将其转换并存储为 Unicode 字符,来对这些字符提供支持。 这些字符存储在服务器中后,在所有后续操作中均视为 Unicode 字符。 可以使用任何中文排序规则,最好使用最新的 100 版本。 所有 _100 级排序规则均支持使用 GB18030 字符进行语言排序。 如果数据包含) 代理项对 (补充字符,则可以使用 SQL Server 2019 (15.x) 中提供的 SC 排序规则来改进搜索和排序。

复杂文种支持

SQL Server 可支持输入、存储、更改和显示复杂文种。 复杂文种包括下列几种情况:

  • 脚本包括从右到左和从左到右两种文字组合,如阿拉伯语和英语文字的组合。

  • 脚本的字符根据其位置或在与其他字符组合时改变形状,如阿拉伯语、印度语和泰语字符。

  • 像泰语这样的语言需要内部词典识别单词,因为这些单词之间不断字。

与 SQL Server 交互的数据库应用程序必须使用支持复杂文种的控件。 在托管代码中创建的标准 Windows 窗体控件支持复杂文种。

任务 主题
介绍如何设置或更改 SQL Server 实例的排序规则。 设置或更改服务器排序规则
介绍如何设置或更改用户数据库的排序规则。 设置或更改数据库排序规则
介绍如何设置或更改数据库中的列的排序规则。 设置或更改列排序规则
介绍如何返回服务器级、数据库级或列级的排序规则信息。 查看排序规则信息
介绍如何编写更易于在不同语言之间移植或更轻松地支持多种语言的 Transact-SQL 语句。 编写国际化 Transact-SQL 语句
介绍如何更改有关日期、时间和货币数据的使用和显示方式的错误消息和首选项的语言。 设置会话语言

SQL Server Best Practices Collation Change

"SQL Server Best Practices Migration to Unicode"

Unicode Consortium 网站

另请参阅

包含数据库的排序规则
创建全文索引时选择语言
sys.fn_helpcollations (Transact-SQL)