对于nvarchar(Unicode)列,COLLATIONS有什么意义?

Roy*_*mir 13 sql-server unicode nvarchar collation sql-server-2008

IVe阅读了很多关于此的内容.

还有一些问题:

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

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

  • 如果我是"FaceBook"并且我需要能够存储语言中的all字符all,那么校对和我的nvarchar列之间的关系是什么?

提前致谢.

Sol*_*zky 13

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

存储在SQL Server中XMLN-prefixed类型中的Unicode数据可以使用单个字符集表示所有语言中的所有字符(大多数情况下,也就是其目标).因此对于NCHAR/ NVARCHAR/ NTEXTdata(我XML不再使用它而遗漏),Collat​​ions不会更改可以存储的字符.对于CHARVARCHAR数据,排序确实影响可以存储为每个排序指向特定代码页的内容,该代码页确定可以存储在值128-255中的内容.

现在,虽然所有字符都有一个默认的排序顺序,但它不可能适用于所有语言和文化.有许多语言共享一些/多个/所有字符,但对于如何对它们进行排序则有不同的规则.例如,在使用这些字母的大多数字母表中,字母"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!';
Run Code Online (Sandbox Code Playgroud)

返回:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!
Run Code Online (Sandbox Code Playgroud)

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

此外,在某些语言中,某些字母或字母组合等同于其他大多数其他语言中的字母.例如,只有在丹麦语中,"å"等同于"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!';
Run Code Online (Sandbox Code Playgroud)

返回:

Danish_Greenlandic_100_CI_AI
Danish_Norwegian_CI_AI
Nope!
Run Code Online (Sandbox Code Playgroud)

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

如果您想深入了解规则,请查看Unicode归类算法(UCA).上面的示例基于该文档中的示例,但我不相信UCA中的所有规则都已实现,特别是因为Windows排序规则(排序不是以开头SQL_为基础)基于Unicode 5.0或6.0,具体取决于哪个您正在使用的操作系统以及安装的.NET Framework版本(有关详细信息,请参阅SortVersion).

这就是Collat​​ions所做的.如果要查看所有可用的排序规则,只需运行以下命令:

SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];
Run Code Online (Sandbox Code Playgroud)


小智 6

如果你有一个char,那么就没有订单.但是,如果你订购了例如人的名字 - 根据整理,不同语言的不同特殊字符的排序也不同.

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

文档相当不错.


Chr*_*lsh 6

我认为原始海报在CODE PAGES和COLLATIONS之间变得混乱.

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

排序规则定义字符的排序顺序,哪些字符变体应视为相同.nvarchar/nchar使用COLLATIONS来定义这些区别.