17

我阅读了很多关于此的内容。

还有一些问题:

我在这里不是在谈论区分大小写...

  • 如果我有一个字符(ש例如)并且他被存储在nvarchar 其中 - 它可以容纳任何东西,我为什么需要collation在这里?

  • 如果我是“FaceBook”并且我需要能够存储语言中的all字符,那么排序规则和我的 nvarchar 列all之间的关系是什么?

提前致谢。

4

3 回答 3

16

存储和表示字符是一回事,知道如何对它们进行排序和比较是另一回事。

Unicode 数据,存储在 SQL Server 中的XMLN-prefixed 类型中,可以用单个字符集表示所有语言中的所有字符(在大多数情况下,这就是它的目标)。所以对于NCHAR/NVARCHAR数据(我NTEXT不应该再使用它了,XML因为它不受排序规则的影响),排序规则不会改变可以存储的字符。对于数据,排序规则CHAR确实影响可以存储的内容,因为每个排序规则指向特定的代码页,这决定了可以存储在值 128 - 255 中的内容。VARCHAR

现在,虽然所有字符都有默认排序顺序,但它不可能适用于所有语言和文化。有许多语言共享一些/许多/所有字符,但是对于如何对它们进行排序有不同的规则。例如,在大多数使用这些字母的字母表中,字母“C”位于字母“D”之前。在美国英语中,“C”和“H”的组合(即“CH”作为两个单独的字母)自然会出现在任何以“D”开头的字符串之前。但是,在一些语言中,“CH”的两个字母组合是特殊的,排“D”之后:

IF (   N'CH' COLLATE Czech_CI_AI > N'D' COLLATE Czech_CI_AI
   AND N'C'  COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI
   AND N'CI' COLLATE Czech_CI_AI < N'D' COLLATE Czech_CI_AI
   ) PRINT 'Czech_CI_AI';

IF (   N'CH' COLLATE Czech_100_CI_AI > N'D' COLLATE Czech_100_CI_AI
   AND N'C'  COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI
   AND N'CI' COLLATE Czech_100_CI_AI < N'D' COLLATE Czech_100_CI_AI
   ) PRINT 'Czech_100_CI_AI';

IF (   N'CH' COLLATE Slovak_CI_AI > N'D' COLLATE Slovak_CI_AI
   AND N'C'  COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI
   AND N'CI' COLLATE Slovak_CI_AI < N'D' COLLATE Slovak_CI_AI
   ) PRINT 'Slovak_CI_AI';

IF (   N'CH' COLLATE Slovak_CS_AS > N'D' COLLATE Slovak_CS_AS
   AND N'C'  COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS
   AND N'CI' COLLATE Slovak_CS_AS < N'D' COLLATE Slovak_CS_AS
   ) PRINT 'Slovak_CS_AS';

IF (   N'CH' COLLATE Latin1_General_100_CI_AS > N'D' COLLATE Latin1_General_100_CI_AS
   AND N'C'  COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS
   AND N'CI' COLLATE Latin1_General_100_CI_AS < N'D' COLLATE Latin1_General_100_CI_AS
   ) PRINT 'Latin1_General_100_CI_AS'
ELSE PRINT 'Nope!';

回报:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

要查看跨不同文化的排序规则示例,请参阅:整理图表

此外,在某些语言中,某些字母或字母组合等同于其他字母,而在大多数其他语言中它们并不相同。例如,只有在丹麦语中,“å”才等同于“aa”。但是,“å”不等于一个“a”:

IF (N'aa' COLLATE Danish_Greenlandic_100_CI_AI =  N'å' COLLATE Danish_Greenlandic_100_CI_AI
AND N'a'  COLLATE Danish_Greenlandic_100_CI_AI <> N'å' COLLATE Danish_Greenlandic_100_CI_AI
   ) PRINT 'Danish_Greenlandic_100_CI_AI';

IF (   N'aa' COLLATE Danish_Norwegian_CI_AI =  N'å' COLLATE Danish_Norwegian_CI_AI
   AND N'a'  COLLATE Danish_Norwegian_CI_AI <> N'å' COLLATE Danish_Norwegian_CI_AI
   ) PRINT 'Danish_Norwegian_CI_AI';

IF (   N'aa' COLLATE Latin1_General_100_CI_AI =  N'å' COLLATE Latin1_General_100_CI_AI
   AND N'a'  COLLATE Latin1_General_100_CI_AI <> N'å' COLLATE Latin1_General_100_CI_AI
   ) PRINT 'Latin1_General_100_CI_AI'
ELSE PRINT 'Nope!';

回报:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!

这一切都非常复杂,我什至没有提到处理从右到左的语言(希伯来语和阿拉伯语)、中文、日语、组合字符等。

如果您想深入了解规则,请查看Unicode Collat​​ion Algorithm (UCA)。上面的示例基于该文档中的示例,尽管我不相信 UCA 中的所有规则都已实施,尤其是因为 Windows 排序规则(排序规则以 开头SQL_)基于 Unicode 5.0 或 6.0,具体取决于哪个您正在使用的操作系统和已安装的 .NET Framework 版本(有关详细信息,请参阅SortVersion)。

这就是排序规则所做的。如果您想查看所有可用的排序规则,只需运行以下命令:

SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];
于 2015-09-30T19:20:31.940 回答
6

如果你有一个字符,那么就没有顺序。但是,如果您订购例如 NAMES of PEOPLE - 不同语言的不同特殊字符的排序方式会有所不同,具体取决于排序规则。

首先,排序规则可能区分大小写 - 在 b 之前显示所有 B - 第二个特殊字符具有取决于排序规则的特殊规则。

文档在这方面非常好。

于 2012-03-18T08:04:00.163 回答
6

我认为原始海报在 CODE PAGES 和 COLLATIONS 之间感到困惑。

nvarchar/nchar 中的“n”允许您使用 unicode 数字集存储文本,该数字集足够大,可以将所有语言中的所有字符(原则上无论如何)都包含一个唯一的数字。这本身与排序规则无关。nvarchar/nchar 不使用 CODE PAGES 来编码/解码每个字符代码的含义。

排序规则定义字符的排序顺序以及哪些字符变体应被视为相同。nvarchar/nchar 确实使用 COLLATIONS 来定义这些区别。

于 2014-01-08T14:36:57.547 回答