Arab_100_CS_AS_KS_WS_SC_UTF8 和 Latin1_General_100_CS_AS_KS_WS_SC_UTF8 有什么区别?

Eng*_*uad 4 sql-server collation utf-8 unicode sql-server-2019

从 SQL Server 2019 开始,它支持 UTF-8 作为排序规则。但是,根据以下查询:

SELECT COLLATIONPROPERTY('Arabic_100_CS_AS_KS_WS_SC_UTF8', 'CodePage')
SELECT COLLATIONPROPERTY('Latin1_General_100_CS_AS_KS_WS_SC_UTF8', 'CodePage');
Run Code Online (Sandbox Code Playgroud)

两者都返回65001Windows 中的 Unicode代码页。此外,所有新_UTF8排序规则都使用代码页65001

SELECT * FROM sys.fn_helpcollations() WHERE name LIKE '%_UTF8';
Run Code Online (Sandbox Code Playgroud)

usingArabic_100_CS_AS_KS_WS_SC_UTF8Latin1_General_100_CS_AS_KS_WS_SC_UTF8as 排序规则之间有什么区别吗?

Sol*_*zky 11

是的,所有_UTF8排序规则都使用代码页 65001,因为这UTF-8 的代码页。您甚至可以通过以下方式在 DOS / 命令窗口中使用 65001:

chcp 65001
Run Code Online (Sandbox Code Playgroud)

尽管并非所有程序和字体都能与它无缝协作。

对于_UTF8归类,代码页不受文化(即Latin1_Generalvs Arabic)的控制,因为它是非_UTF8归类的,因为代码页指示用于VARCHAR数据(即 8 位字符数据)的特定 8 位编码。对于非 Unicode 8 位编码,区域性通常与作为字符集的代码页相关联(例如,Latin1 是代码页 Windows-1252,它在 128-255 范围内的字符不同于作为代码的 Windows-1255希伯来语页面)。但对于UTF-8,它为奇,无所不包的字符集是Unicode的8位编码。

至于Arabic_100_CS_AS_KS_WS_SC_UTF8Latin1_General_100_CS_AS_KS_WS_SC_UTF8go之间的差异,它实际上只是用于对各种字符进行排序和比较的特定于文化的规则。当然,这两种语言并没有真正共享任何字符,但是在处理某些代码点的方式上仍然存在差异。

查看“Windows Server 2008 排序权重表”文件(据我_100_所知,这是版本排序规则主要基于的内容),我找不到这两个排序规则之间的任何排序/比较差异。因此,它们在行为方面可能相同。但是,它们在某种意义上并不相同,因为它们仍然具有不同的 LCID(区域设置/文化标识符),因此将它们的值转换为非 UTF8VARCHAR可能会导致数据丢失/损坏,以及查看排序规则的任何进程/功能确定其他一些行为可能会有不同的表现。


话虽如此,我确实找到了使用乌尔都语归类时阿拉伯字符行为差异的示例,因为这些归类确实对默认排序权重进行了一些修改(在“Windows Server 2008 排序权重表”文件中注册了 9 个) .

在看“德Marbuta”字符(U + 0629),它具有29在默认表中的权重(即用于英语(美国)/ Latin1的表),它具有较低的排序权重比“Peheh”字符(U +06A6),默认权重为 137。41 表示字符所在的“脚本”,这些都是阿拉伯字符。然而,乌尔都语归类修改“德Marbuta”(U + 0629)的排序权重为183,然后具有较高的排序权重比“Peheh”(U + 06A6),仍然137。

-- Default
0x0629  41  29  2   2   ;Arabic Teh Marbuta -- ?
0x06a6  41  137 2   2   ;Arabic Peheh       -- ?

-- Urdu modifications
0x0629  41  183 2   2   ;Teh Marbuta        -- ?
Run Code Online (Sandbox Code Playgroud)

如果我们使用Latin1_General_100_CS_AS_KS_WS_SC_UTF8or对这两个字符进行排序Arabic_100_CS_AS_KS_WS_SC_UTF8,我们应该得到默认行为。而且,即使我们使用Yakut排序规则,它使用 Cyrillic 脚本并对默认排序权重进行了自己的修改,它也不会修改这些阿拉伯字符中的任何一个,因此它们的行为应该与使用 a Latin1_GeneralorArabic排序规则时相同:

chcp 65001
Run Code Online (Sandbox Code Playgroud)

上面显示的所有三个查询都返回以下结果:

ID    TheChar
1     ?
2     ?
Run Code Online (Sandbox Code Playgroud)

但是,当我们切换到Urdu排序规则时,这两个字符的顺序确实发生了变化:

-- Default
0x0629  41  29  2   2   ;Arabic Teh Marbuta -- ?
0x06a6  41  137 2   2   ;Arabic Peheh       -- ?

-- Urdu modifications
0x0629  41  183 2   2   ;Teh Marbuta        -- ?
Run Code Online (Sandbox Code Playgroud)

返回:

ID    TheChar
2     ?
1     ?
Run Code Online (Sandbox Code Playgroud)

最后,请记住,虽然很少遇到这种情况,但排序规则也会影响大写/小写映射。我相信这仅限于Azeri_*Turkish排序规则,并且仅适用于字母“i”和“I”(这些文化有带点的大写“I”和无点的小写“i”),但仍然最好意识到潜力:

SELECT *
FROM   (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Latin1_General_100_CS_AS_KS_WS_SC_UTF8 ASC

SELECT *
FROM   (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Arabic_100_CS_AS_KS_WS_SC_UTF8 ASC


SELECT *
FROM   (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Yakut_100_CS_AS_KS_WS_SC_UTF8 ASC
Run Code Online (Sandbox Code Playgroud)

返回:

Arabic   Turkish   Azeri_Cyrillic   Azeri_Latin
I        ?         ?                ?
Run Code Online (Sandbox Code Playgroud)