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

时间:2012-03-18 07:35:06

标签: sql-server sql-server-2008 unicode collation nvarchar

IVe对此有很多了解。

还有一些问题:

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

  • 如果我有一个字母(例如ש),并且他存储在nvarchar中 - 它可以保存任何内容,为什么我需要collation

  • 如果我是“FaceBook”并且我需要能够存储来自all种语言的all个字符,那么校对和我的nvarchar列之间的关系是什么

提前致谢。

3 个答案:

答案 0 :(得分:12)

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

存储在SQL Server中XMLN前缀类型的Unicode数据可以用单个字符表示所有语言中的所有字符(大多数情况下,这是它的目标)组。因此对于XML / NCHAR / NVARCHAR数据(因为它不应再使用而遗漏NTEXT),归类不会更改可以存储的字符。对于CHARVARCHAR数据,归类 do 会影响每个归类指向特定代码页的内容,该代码页确定可以存储在值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!';

返回:

Czech_CI_AI
Czech_100_CI_AI
Slovak_CI_AI
Slovak_CS_AS
Nope!

要查看各种文化的排序规则示例,请参阅:Collation Charts

此外,在某些语言中,某些字母或字母组合等同于其他大多数其他语言的字母。例如,只有在丹麦语中,“å”等同于“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 Collation Algorithm (UCA)。上面的示例基于该文档中的示例,但我不相信UCA中的所有规则都已实现,特别是因为Windows排序规则(排序不是SQL_开头)基于Unicode 5.0或6.0,具体取决于您使用的操作系统和安装的.NET Framework版本(有关详细信息,请参阅SortVersion)。

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

SELECT [name] FROM sys.fn_helpcollations() ORDER BY [name];

答案 1 :(得分:6)

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

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

文档非常好。

答案 2 :(得分:6)

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

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

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