SQL Server 中的排序规则可为您的数据提供排序规则、区分大小写属性和区分重音属性。 与字符数据类型一起使用的排序规则,例如 char
和 varchar
,指定了代码页及可以通过该数据类型表示的相应字符。 无论是安装 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
规则区分大小写、区分重音、区分假名和区分宽度。 下表描述了与这些选项关联的行为。
选项 | DESCRIPTION |
---|---|
区分大小写 (_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 平台是小端架构,因此 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 子句来解决此问题。 有关详细信息,请参阅 COLLATE(Transact-SQL)。
列级排序规则
创建或更改表时,可以使用 COLLATE 子句为每个字符串列指定排序规则。 如果未指定排序规则,则为该列分配数据库的默认排序规则。
表达式级排序规则
表达式级排序规则在语句运行时设置,并且影响结果集的返回方式。 这使 ORDER BY 排序结果能够根据区域设置进行特定处理。 使用 COLLATE 子句(如以下示例)实现表达式级别排序规则:
SELECT name FROM customer ORDER BY name COLLATE Latin1_General_CS_AI;
地区
区域设置是一组与位置或文化相关的信息。 这可以包括口语的名称和标识符、用于编写语言的脚本以及文化约定。 排序规则可以与一个或多个区域设置相关联。 有关详细信息,请参阅 Microsoft 分配的区域设置 ID。
代码页
代码页是给定脚本的有序字符集,其中数值索引(即码位值)与每个字符相关联。 Windows 代码页通常称为 字符集 或 字符集。 代码页用于支持不同的 Windows 系统区域设置所使用的字符集和键盘布局。
排序方式
排序顺序指定数据值的排序方式。 这会影响数据比较的结果。 数据的排序通过使用排序规则而实现,且可使用索引对排序进行优化。
Unicode 支持
Unicode 是一种将码位映射到字符的标准。 因为它旨在涵盖世界所有语言的所有字符,因此无需不同的代码页来处理不同的字符集。 如果存储反映多种语言的字符数据,请始终使用 Unicode 数据类型(nchar
和ntext
nvarchar
)而不是非 Unicode 数据类型(char
和varchar
text
)。
非 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 和 Open Database Connectivity (ODBC) 3.7 或更高版本的 Unicode 客户端。
使用 DB-Library 和 ODBC 版本 3.6 或更低版本的非 Unicode 客户端。
下表提供有关将多语言数据与 Unicode 和非 Unicode 服务器的各种组合结合使用的信息。
服务器 | 客户 | 优点或限制 |
---|---|---|
Unicode | Unicode | 由于 Unicode 数据将在整个系统中使用,因此此方案可提供最佳性能和保护,防止检索到的数据损坏。 这是 ActiveX 数据对象(ADO)、OLE DB 和 ODBC 版本 3.7 或更高版本的情况。 |
Unicode | 非 Unicode | 在这种情况下,特别是在运行较新操作系统的服务器与运行较旧版本 SQL Server 或较旧操作系统的客户端之间建立连接时,将数据传输到客户端计算机可能会出现限制或错误。 服务器上的 Unicode 数据将尝试映射到非 Unicode 客户端上的相应代码页以转换数据。 |
非 Unicode | Unicode | 这不是使用多语言数据的理想配置。 无法将 Unicode 数据写入非 Unicode 服务器。 在向服务器的代码页之外的服务器发送数据时,很可能会发生问题。 |
非 Unicode | 非 Unicode | 这是对多语言数据有极大局限性的方案。 您只可使用一个代码页。 |
补充字符
SQL Server 提供数据类型,例如 nchar
和 nvarchar
存储 Unicode 数据。 这些数据类型采用名为 UTF-16 的格式对文本进行编码。 Unicode联盟为每个字符分配一个唯一的码位,该码位的范围是从0x0000到0x10FFFF的值。 最常用的字符具有代码点值,这些值将适合内存和磁盘上的 16 位单词,但具有大于0xFFFF的代码点值的字符需要两个连续 16 位单词。 这些字符称为 补充字符,两个连续 16 位单词称为 代理项对。
如果使用增补字符:
只有在 90 版本或更高版本的排序规则中才可以将增补字符用于排序和比较操作。
所有 _100 级别排序规则都支持使用补充字符进行语言排序。
不支持在元数据中使用补充字符,例如数据库对象的名称。
在 SQL Server 2012 中引入,新的补充字符(SC)排序规则系列可用于数据类型
nchar
,nvarchar
以及sql_variant
。 例如:Latin1_General_100_CI_AS_SC
,或者如果使用日语排序规则,Japanese_Bushu_Kakusu_100_CI_AS_SC
。SC 标志可应用于:
版本 90 Windows 排序规则
版本 100 Windows 排序规则
SC 标志不能应用于:
80 版本非版本化 Windows 排序规则
BIN 或 BIN2 二进制排序规则
SQL* 排序规则
下表比较了某些字符串函数和字符串运算符在使用补充字符时,有无 SC 排序规则的行为。
字符串函数或运算符 | 使用 SC 排序规则 | 没有 SC 排序规则 |
---|---|---|
CHARINDEX 莱恩 PATINDEX |
UTF-16 代理对被视为一个代码点。 | UTF-16 代理项对计为两个代码点。 |
左 REPLACE 反向 右 子串 东西 |
这些函数将每个代理项对视为单个代码点,并按预期工作。 | 这些函数可以拆分任何代理项对并导致意外结果。 |
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 语句 |
说明如何更改错误消息的语言,以及日期、时间和货币数据的使用和显示首选项。 | 设置会话语言 |