本节描述Unicode字符集可用的排序规则及其区别属性。有关Unicode的一般信息,请参见第10.9节“Unicode支持”.
MySQL支持多个Unicode字符集:
utf8mb4
: Unicode字符集的UTF-8编码,每个字符使用1 ~ 4个字节。utf8mb3
: Unicode字符集的UTF-8编码,每个字符使用一到三个字节。use utf8
:别名。utf8mb3
.ucs2
: Unicode字符集的UCS-2编码,每个字符使用两个字节。utf16
:每个字符使用2字节或4字节的Unicode字符集的UTF-16编码。就像ucs2
但是扩展了辅助字符。utf16le
: Unicode字符集的UTF-16LE编码。就像utf16
但是是小端而不是大端。utf32
:每个字符4字节的Unicode字符集的UTF-32编码。
utf8mb4
,utf16
,utf16le
,utf32
支持基本多语言平面(BMP)字符和位于BMP之外的补充字符。use utf8
而且ucs2
只支持BMP字符。
大多数Unicode字符集都有一个通用排序规则(由_general
在名称中或由于没有语言说明符),一个二进制排序规则(由_bin
在名称中),以及几个特定于语言的排序规则(由语言说明符指示)。例如,对于utf8mb4
,utf8mb4_general_ci
而且utf8mb4_bin
它是通用的和二进制的排序,和utf8mb4_danish_ci
是其特定于语言的排序规则之一。
排序规则支持utf16le
是有限的。唯一可用的排序规则是utf16le_general_ci
而且utf16le_bin
.这些类似于utf16_general_ci
而且utf16_bin
.
MySQL实现了
根据Unicode排序算法(UCA)进行排序http://www.unicode.org/reports/tr10/.排序使用版本4.0.0 UCA权重键:http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt.的xxx
_unicode_ci
collations仅部分支持Unicode Collation算法。不支持某些字符,并且不完全支持组合标记。这主要影响越南语、约鲁巴语和一些较小的语言,如纳瓦霍语。在字符串比较中,组合字符被认为不同于用单个unicode字符编写的同一字符,并且这两个字符被认为具有不同的长度(例如,由xxx
_unicode_ciCHAR_LENGTH ()
函数或结果集元数据)。
基于高于4.0.0的UCA版本的Unicode排序规则将版本包含在排序规则名称中。因此,utf8_unicode_520_ci
是基于UCA 5.2.0权重键(http://www.unicode.org/Public/UCA/5.2.0/allkeys.txt).
的低()
而且上()
函数根据其参数的排序规则执行大小写折叠。只有当参数排序使用足够高的UCA版本时,这些函数才会转换仅在高于4.0.0的Unicode版本中具有大写和小写版本的字符。
如果仅基于Unicode排序算法(UCA)的排序不适用于某种语言,MySQL将实现特定于语言的Unicode排序。特定于语言的排序规则是基于uca的,并带有额外的语言裁剪规则。这类规则的示例将在本节后面出现。对于关于特定语言顺序的问题,unicode.org提供公共区域数据存储库(CLDR)的整理图http://www.unicode.org/cldr/charts/30/collation/index.html.
下表中显示的语言名称表示特定于语言的排序规则。Unicode字符集可能包括这些语言中的一种或多种的排序规则。
表10.3 Unicode排序规则语言说明符
语言 | 语言说明符 |
---|---|
古典拉丁语 | 罗马 |
克罗地亚 | 克罗地亚 |
捷克 | 捷克 |
丹麦 | 丹麦 |
世界语 | 世界语 |
爱沙尼亚 | 爱沙尼亚 |
德国电话簿订单 | german2 |
匈牙利 | 匈牙利 |
冰岛 | 冰岛 |
拉脱维亚 | 拉脱维亚 |
立陶宛 | 立陶宛 |
波斯 | 波斯 |
波兰的 | 波兰的 |
罗马尼亚 | 罗马尼亚 |
僧伽罗语 | 僧伽罗语 |
斯洛伐克语 | 斯洛伐克语 |
斯洛维尼亚语 | 斯洛维尼亚语 |
现代西班牙语 | 西班牙语 |
传统的西班牙 | spanish2 |
瑞典 | 瑞典 |
土耳其 | 土耳其 |
越南 | 越南 |
克罗地亚语的排序是为这些克罗地亚字母量身定做的:Č
,Ć
,Dž
,Đ
,Lj
,新泽西
,Š
,Ž
.
丹麦语排序规则也可用于挪威语。
对于古典拉丁语排序,我
而且J
比较为相等,和U
而且V
平等比较。
西班牙语排序可用于现代西班牙语和传统西班牙语。为,n
(n-波浪号)是一个单独的字母之间n
而且o
.此外,对于传统西班牙语,ch
是一个单独的字母之间c
而且d
,噢
是一个单独的字母之间l
而且米
.
传统的西班牙语排序也可用于阿斯图里语和加利西亚语。
瑞典的整理包括瑞典的规则。例如,在瑞典语中,以下关系成立,这不是说德语或法语的人所期望的:
Ü = y < Ö
对于任何Unicode字符集,使用
的整理速度比xxx
_general_ci
排序。的比较xxx
_unicode_ciutf8_general_ci
与比较相比,排序更快,但稍不正确utf8_unicode_ci
.原因是utf8_unicode_ci
支持扩展等映射;也就是说,当一个字符与其他字符的组合比较相等时。例如,ß
等于党卫军
德语和其他一些语言。utf8_unicode_ci
还支持缩写和可忽略字符。utf8_general_ci
是不支持展开、收缩或可忽略字符的遗留排序规则。它只能在字符之间进行一对一的比较。
为了进一步说明,以下等式在两者中都成立utf8_general_ci
而且utf8_unicode_ci
(关于这在比较或搜索中的影响,请参见第10.8.6节“排序效果的例子”):
Ä = a Ö = o Ü = u
排序规则之间的区别是,对于utf8_general_ci
:
ß = s
而对于utf8_unicode_ci
,支持德语DIN-1顺序(也称为字典顺序):
ß = ss
MySQL实现use utf8
如果使用排序,则指定语言的排序规则utf8_unicode_ci
这对一门语言来说并不适用。例如,utf8_unicode_ci
适用于德语字典顺序和法语,所以不需要创建特殊的use utf8
排序。
utf8_general_ci
除此之外,德语和法语也都令人满意ß
等于年代
,而不是党卫军
.如果这对于您的应用程序是可以接受的,那么您应该使用utf8_general_ci
因为它更快。如果这是不可接受的(例如,如果您需要德语字典顺序),则使用utf8_unicode_ci
因为这样更准确。
如果您需要德语DIN-2(电话簿)订购,请使用utf8_german2_ci
排序规则,它比较下列相等的字符集:
Ä = Æ = AE Ö = OE Ü = UE ß = ss
utf8_german2_ci
类似于latin1_german2_ci
,但后者无法相提并论Æ
等于AE
或œ
等于OE
.没有utf8_german_ci
对应于latin1_german_ci
for German dictionary order becauseutf8_general_ci
就足够了。
字符排序权值的确定如下:
的所有Unicode排序规则
_bin
(二进制)排序,MySQL执行表查找来查找字符的排序权重。为
_bin
排序规则中,权重基于代码点,可能会添加前导零字节。
控件可以显示排序权重WEIGHT_STRING ()
函数。(见第12.8节“字符串函数和操作符”)。如果排序使用权重查找表,但字符不在表中(例如,因为它是<年代pan class="quote">”<年代pan class="quote">新年代pan>”年代pan>字符),排序权重的确定变得更加复杂:
对于一般排序规则中的BMP字符(
),权重为码位。xxx
_general_ci对于UCA排序规则中的BMP字符(例如,
和特定于语言的排序规则),则应用以下算法:xxx
_unicode_ciif (code >= 0x3400 && code <= 0x4DB5) base= 0xFB80;/* CJK表意字扩展名*/ else if (code >= 0x4E00 && code <= 0x9FA5) base= 0xFB40;/* CJK表意文字*/ else base= 0xFBC0;/*所有其他字符*/ aaaa= base +(代码>> 15);bbbb= (code & 0x7FFF) | 0x8000;
结果是由两个排序元素组成的序列,
aaaa级
紧随其后的是bbbb
.例如:mysql> SELECT HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci));+----------------------------------------------------------+ | 十六进制(WEIGHT_STRING (_ucs2 0 x04cf核对ucs2_unicode_ci )) | +----------------------------------------------------------+ | FBC084CF | +----------------------------------------------------------+
因此,
西里尔字母帕洛奇卡
对于所有UCA 4.0.0排序规则,大于西里尔字母PALOCHKA
.在UCA 5.2.0排序中,所有的palochka都在一起排序。对于一般排序规则中的补充字符,权重为的权重
0xfffd替换字符
.对于UCA 4.0.0排序规则中的补充字符,它们的排序权值为0 xfffd
.也就是说,对于MySQL,所有的补充字符都是相等的,并且比几乎所有的BMP字符都大。一个关于Deseret字符和的例子
数(不同的)
:创建表t (s1 VARCHAR(5) CHARACTER SET utf32 COLLATE utf32_unicode_ci);INSERT INTO t VALUES (0xfffd);/*替换字符*/插入t值(0x010412);/*插入t值(0x010413);/*从t中选择COUNT(s1);
结果是2,因为在MySQL
排序规则,替换字符的权重为xxx
_unicode_ci0 x0dc6
,而Deseret Bee和Deseret Tee的重量均为0 xfffd
.(是utf32_general_ci
如果使用排序规则,则结果为1,因为所有三个字符的权重都为0 xfffd
在这种整理中。)一个楔形文字和的例子
WEIGHT_STRING ()
:/*插入字符串中的四个字符是:00000041 #拉丁大写字母A 0001218f# CUNEIFORM SIGN KAB 000121A7 # CUNEIFORM SIGN KISH 00000042 #拉丁大写字母B */ CREATE TABLE t (s1 CHAR(4) CHARACTER SET utf32 COLLATE utf32_unicode_ci);INSERT INTO t VALUES (0x000000410001218f000121a700000042);SELECT HEX(WEIGHT_STRING(s1)) FROM t;
结果是:
0e33 FFFD FFFD 0e4a
0 e33
而且0 e4a
主权重是指UCA 4.0.0.FFFD
是KAB和KISH的权重。所有补充字符彼此相等的规则不是最优的,但预计不会造成麻烦。这些字符是非常罕见的,所以一个多字符字符串完全由补充字符组成是非常罕见的。在日本,由于辅助字符是晦涩的汉字表意文字,一般用户并不关心它们的顺序。如果你真的想按MySQL规则排序,然后按代码点值排序,这很简单:
ORDER BY s1 COLLATE utf32_unicode_ci, s1 COLLATE utf32_bin
对于基于高于4.0.0的UCA版本的补充字符(例如,
),辅助字符不一定都有相同的排序权值。有些具有来自UCA的明确权重xxx
_unicode_520_ciallkeys.txt
文件。其他的则通过这个算法计算出权重:Aaaa = base +(代码>> 15);bbbb= (code & 0x7FFF) | 0x8000;
两者之间是有区别的<年代pan class="quote">”<年代pan class="quote">按字符的代码值排序年代pan>”年代pan>而且<年代pan class="quote">”<年代pan class="quote">根据字符的二进制表示顺序,年代pan>”年代pan>只出现在utf16_bin
因为有替身。
假设utf16_bin
的二进制排序utf16
)是一个二元比较<年代pan class="quote">”<年代pan class="quote">一个字节一个字节年代pan>”年代pan>而不是<年代pan class="quote">”<年代pan class="quote">一个字符接一个字符。年代pan>”年代pan>如果是这样的话,字符的顺序utf16_bin
会和顺序不同吗utf8_bin
.例如,下面的图表显示了两个稀有字符。第一个字符在范围内E000
-飞行符
,所以它大于替代,但小于补充。第二个字符是补语。
代码点字符utf8 utf16 ---------- --------- --------- 0FF9D半宽片假名字母N EF BE 9D FF9D 10384乌格里字母DELTA F0 90 8E 84 D8 00 DF 84
图表中的两个字符是按代码点值排列的0 xff9d
<0 x10384
.它们的顺序是use utf8
价值的,因为0 xef
<0 xf0
.但它们不是按顺序排列的utf16
值,如果我们使用逐字节比较,因为0 xff
>0 xd8
.
所以MySQL的utf16_bin
排序规则不是<年代pan class="quote">”<年代pan class="quote">一个字节一个字节。年代pan>”年代pan>它是<年代pan class="quote">”<年代pan class="quote">通过代码点。年代pan>”年代pan>当MySQL看到一个补充字符编码utf16
,它将转换为字符的代码点值,然后进行比较。因此,utf8_bin
而且utf16_bin
都是同样的顺序。这与UCS_BASIC排序规则的SQL:2008标准要求是一致的:<年代pan class="quote">”<年代pan class="quote">UCS_BASIC是一种排序规则,其中顺序完全由被排序的字符串中字符的Unicode标量值决定。适用于UCS字符库。由于每个字符集都是UCS字符集的子集,因此UCS_BASIC排序规则可能适用于每个字符集。注11:字符的Unicode标量值是作为无符号整数处理的编码点。年代pan>”年代pan>
如果字符集为ucs2
,比较是逐字节的,但是ucs2
字符串不应该包含代理。