“MySQL 字符集:支持的字符集和排序规则”的版本间差异
(建立内容为“category:MySQL == 关于 == 要列出可用的字符集及其默认排序规则,请使用“'''SHOW CHARACTER SET'''”或查询“'''INFORMATION_SCHEMA'''…”的新页面) |
|||
第15行: | 第15行: | ||
== Unicode 字符集 == | == Unicode 字符集 == | ||
MySQL 支持多种 Unicode 字符集: | |||
# utf8mb4:Unicode 字符集的 UTF-8 编码,每个字符使用 1-4 个字节。 | |||
# utf8mb3:Unicode 字符集的 UTF-8 编码,每个字符使用一到三个字节。 | |||
# utf8:utf8mb3的别名。 | |||
# ucs2:Unicode 字符集的 UCS-2 编码,每个字符使用两个字节。 | |||
# utf16:Unicode 字符集的 UTF-16 编码,每个字符使用两个或四个字节。类似于ucs2,但扩展了辅助字符。 | |||
# utf16le:Unicode 字符集的 UTF-16LE 编码。像utf16,但是小端而不是大端。 | |||
# utf32:Unicode 字符集的 UTF-32 编码,每个字符使用四个字节。 | |||
* utf8mb4,utf16,utf16le和utf32支持 BMP 之外的基本多语言平面(BMP)字符和补充字符。 utf8和ucs2仅支持 BMP 字符。 | |||
大多数 Unicode 字符集具有: | |||
# 常规排序规则(名称中用“_general”表示或没有语言说明符), | |||
# 二进制排序规则(名称中用“_bin”表示) | |||
# 以及几种特定于语言的排序规则(由语言说明符表示)。 | |||
* utf16le 的排序规则支持是有限的。唯一可用的排序规则是 utf16le_general_ci 和 utf16le_bin 。这类似于 utf16_general_ci 和 utf16_bin。 | |||
例如,对于 utf8mb4:utf8mb4_general_ci 和 utf8mb4_bin 是其常规归类和二进制归类,而 utf8mb4_danish_ci 是其特定于语言的归类之一。 | |||
=== Unicode 排序算法 === | |||
MySQL 根据“[http://www.unicode.org/reports/tr10/ UNICODE COLLATION ALGORITHM]”所述的 Unicode 排序算法(UCA)实现“xxx_unicode_ci”排序规则。 | |||
* “xxx_unicode_ci”排序仅部分支持 Unicode 归类算法。不支持某些字符,并且不完全支持组合标记。这主要影响越南语,约鲁巴语和一些较小的语言,例如 Navajo。 | |||
* 在字符串比较中,组合字符被认为与用单个 unicode 字符编写的相同字符不同,并且两个字符被认为具有不同的长度(例如,由“CHAR_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)。 | |||
* “LOWER()”和“UPPER()”函数根据其参数的排序规则执行大小写转换。仅当参数排序规则使用足够高的 UCA 版本时,这些函数才能转换仅在 Unicode 版本高于 4.0.0 中具有大写和小写版本的字符。 | |||
=== 特定语言的排序规则 === | |||
如果仅基于 Unicode 排序规则算法(UCA)的排序不适用于某种语言,则 MySQL 将实现特定于语言的 Unicode 排序规则。特定于语言的排序规则基于 UCA,并带有其他语言定制规则。 | |||
下表中显示的语言名称表示特定于语言的排序规则。 Unicode 字符集可以包括一种或多种这些语言的排序规则: | |||
{| class="wikitable" | |||
! Language !! Language Specifier | |||
|- | |||
| Classical Latin || roman | |||
|- | |||
| Croatian || croatian | |||
|- | |||
| Czech || czech | |||
|- | |||
| Danish || danish | |||
|- | |||
| Esperanto || esperanto | |||
|- | |||
| Estonian || estonian | |||
|- | |||
| German phone book order || german2 | |||
|- | |||
| Hungarian || hungarian | |||
|- | |||
| Icelandic || icelandic | |||
|- | |||
| Latvian || latvian | |||
|- | |||
| Lithuanian || lithuanian | |||
|- | |||
| Persian || persian | |||
|- | |||
| Polish || polish | |||
|- | |||
| Romanian || romanian | |||
|- | |||
| Sinhala || sinhala | |||
|- | |||
| Slovak || slovak | |||
|- | |||
| Slovenian || slovenian | |||
|- | |||
| Modern Spanish || spanish | |||
|- | |||
| Traditional Spanish || spanish2 | |||
|- | |||
| Swedish || swedish | |||
|- | |||
| Turkish || turkish | |||
|- | |||
| Vietnamese || vietnamese | |||
|} | |||
=== _general_ci 与_unicode_ci 排序规则 === | |||
'''对于任何 Unicode 字符集,使用“xxx_general_ci”排序规则执行的操作都比使用“xxx_unicode_ci”排序规则进行的操作要快。''' | |||
例如,对“utf8_general_ci”排序规则的比较比对“utf8_unicode_ci”的比较更快,但正确性稍差。原因是“utf8_unicode_ci”支持映射等扩展(也就是说,一个字符与其他字符的组合相等时)。例如,在德语和某些其他语言中,“ß”等于“ss”。 “utf8_unicode_ci”还支持收缩和可忽略字符。而“utf8_general_ci”是不支持扩展,收缩或可忽略字符的传统排序规则,它只能在字符之间进行一对一比较。 | |||
如: | |||
<syntaxhighlight lang="xml"> | |||
ß = s | |||
</syntaxhighlight> | |||
对于utf8_general_ci是正确的 | |||
<syntaxhighlight lang="xml"> | |||
ß = ss | |||
</syntaxhighlight> | |||
对于utf8_unicode_ci是正确的。 | |||
* 如果使用 utf8_unicode_ci 的排序不适用于某种语言,则 MySQL 将实现 utf8 语言特定的排序规则。例如,utf8_unicode_ci 适用于德语字典顺序和法语,因此无需创建特殊的 utf8 排序规则。 | |||
=== 字符排序权重 === | |||
字符的归类权重确定如下: | |||
# 对于除“_bin”(二进制)排序规则外的所有 Unicode 归类,MySQL 执行 table 查找以查找字符的归类权重。 | |||
# 对于“_bin”排序规则,权重基于代码点,可能添加了前导零字节。 | |||
* 可以使用“'''WEIGHT_STRING()'''”函数显示整理权重。 | |||
如果排序规则使用权重查找 table,但是 table 中没有字符,则排序权重确定变得更加复杂: | |||
# 对于一般排序规则(“xxx_general_ci”)中的 BMP 字符,权重是代码点。 | |||
# 对于 UCA 归类中的 BMP 字符(例如“xxx_unicode_ci”和特定于语言的排序规则),适用以下算法: | |||
#: <syntaxhighlight lang="xml"> | |||
if (code >= 0x3400 && code <= 0x4DB5) | |||
base= 0xFB80; /* CJK Ideograph Extension */ | |||
else if (code >= 0x4E00 && code <= 0x9FA5) | |||
base= 0xFB40; /* CJK Ideograph */ | |||
else | |||
base= 0xFBC0; /* All other characters */ | |||
aaaa= base + (code >> 15); | |||
bbbb= (code & 0x7FFF) | 0x8000; | |||
</syntaxhighlight> | |||
#: 结果是两个整理元素的序列,aaaa后跟bbbb。例如: | |||
#: <syntaxhighlight lang="xml"> | |||
mysql> SELECT HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)); | |||
+----------------------------------------------------------+ | |||
| HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)) | | |||
+----------------------------------------------------------+ | |||
| FBC084CF | | |||
+----------------------------------------------------------+ | |||
</syntaxhighlight> | |||
# 对于一般排序规则中的补充字符,权重是“0xfffd REPLACEMENT CHARACTER的权重”。对于 UCA 4.0.0 排序规则中的补充字符,其归类权重为“0xfffd”。也就是说,'''对于 MySQL,所有补充字符都彼此相等,并且几乎大于所有 BMP 字符'''。 | |||
#* 所有补充字符都相等的规则不是最佳的,但是不会引起麻烦。这些字符非常少见,因此由多字符组成的字符串完全由补充字符组成非常罕见。如果您确实希望按 MySQL 规则对行进行排序,然后再按'''码点值'''对行进行排序,则很简单: | |||
#*: '''<syntaxhighlight lang="xml"> | |||
ORDER BY s1 COLLATE utf32_unicode_ci, s1 COLLATE utf32_bin | |||
</syntaxhighlight>''' | |||
# '''对于基于高于 4.0.0 的 UCA 版本的补充字符,补充字符不一定都具有相同的整理重量'''(例如“xxx_unicode_520_ci”)。 | |||
=== 其他信息 === | |||
“xxx_general_mysql500_ci”排序规则保留原始“xxx_general_ci”排序规则在 5.1.24 之前的顺序,并允许对在 MySQL 5.1.24 之前创建的 table 进行升级(缺陷号 27877)。【???】 | |||
== 亚洲字符集 == | == 亚洲字符集 == | ||
== 二进制字符集 == | == 二进制字符集 == |
2021年3月29日 (一) 03:56的版本
关于
要列出可用的字符集及其默认排序规则,请使用“SHOW CHARACTER SET”或查询“INFORMATION_SCHEMA”中的“CHARACTER_SETS”表。
MySQL支持的字符集:
- Unicode 字符集
- 西欧字符集(略)
- 中欧字符集(略)
- 南欧和中东字符集(略)
- 波罗的海字符集(略)
- 西里尔字符集(略)
- 亚洲字符集
- 二进制字符集
Unicode 字符集
MySQL 支持多种 Unicode 字符集:
- utf8mb4:Unicode 字符集的 UTF-8 编码,每个字符使用 1-4 个字节。
- utf8mb3:Unicode 字符集的 UTF-8 编码,每个字符使用一到三个字节。
- utf8:utf8mb3的别名。
- ucs2:Unicode 字符集的 UCS-2 编码,每个字符使用两个字节。
- utf16:Unicode 字符集的 UTF-16 编码,每个字符使用两个或四个字节。类似于ucs2,但扩展了辅助字符。
- utf16le:Unicode 字符集的 UTF-16LE 编码。像utf16,但是小端而不是大端。
- utf32:Unicode 字符集的 UTF-32 编码,每个字符使用四个字节。
- utf8mb4,utf16,utf16le和utf32支持 BMP 之外的基本多语言平面(BMP)字符和补充字符。 utf8和ucs2仅支持 BMP 字符。
大多数 Unicode 字符集具有:
- 常规排序规则(名称中用“_general”表示或没有语言说明符),
- 二进制排序规则(名称中用“_bin”表示)
- 以及几种特定于语言的排序规则(由语言说明符表示)。
- utf16le 的排序规则支持是有限的。唯一可用的排序规则是 utf16le_general_ci 和 utf16le_bin 。这类似于 utf16_general_ci 和 utf16_bin。
例如,对于 utf8mb4:utf8mb4_general_ci 和 utf8mb4_bin 是其常规归类和二进制归类,而 utf8mb4_danish_ci 是其特定于语言的归类之一。
Unicode 排序算法
MySQL 根据“UNICODE COLLATION ALGORITHM”所述的 Unicode 排序算法(UCA)实现“xxx_unicode_ci”排序规则。
- “xxx_unicode_ci”排序仅部分支持 Unicode 归类算法。不支持某些字符,并且不完全支持组合标记。这主要影响越南语,约鲁巴语和一些较小的语言,例如 Navajo。
- 在字符串比较中,组合字符被认为与用单个 unicode 字符编写的相同字符不同,并且两个字符被认为具有不同的长度(例如,由“CHAR_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)。
- “LOWER()”和“UPPER()”函数根据其参数的排序规则执行大小写转换。仅当参数排序规则使用足够高的 UCA 版本时,这些函数才能转换仅在 Unicode 版本高于 4.0.0 中具有大写和小写版本的字符。
特定语言的排序规则
如果仅基于 Unicode 排序规则算法(UCA)的排序不适用于某种语言,则 MySQL 将实现特定于语言的 Unicode 排序规则。特定于语言的排序规则基于 UCA,并带有其他语言定制规则。
下表中显示的语言名称表示特定于语言的排序规则。 Unicode 字符集可以包括一种或多种这些语言的排序规则:
Language | Language Specifier |
---|---|
Classical Latin | roman |
Croatian | croatian |
Czech | czech |
Danish | danish |
Esperanto | esperanto |
Estonian | estonian |
German phone book order | german2 |
Hungarian | hungarian |
Icelandic | icelandic |
Latvian | latvian |
Lithuanian | lithuanian |
Persian | persian |
Polish | polish |
Romanian | romanian |
Sinhala | sinhala |
Slovak | slovak |
Slovenian | slovenian |
Modern Spanish | spanish |
Traditional Spanish | spanish2 |
Swedish | swedish |
Turkish | turkish |
Vietnamese | vietnamese |
_general_ci 与_unicode_ci 排序规则
对于任何 Unicode 字符集,使用“xxx_general_ci”排序规则执行的操作都比使用“xxx_unicode_ci”排序规则进行的操作要快。
例如,对“utf8_general_ci”排序规则的比较比对“utf8_unicode_ci”的比较更快,但正确性稍差。原因是“utf8_unicode_ci”支持映射等扩展(也就是说,一个字符与其他字符的组合相等时)。例如,在德语和某些其他语言中,“ß”等于“ss”。 “utf8_unicode_ci”还支持收缩和可忽略字符。而“utf8_general_ci”是不支持扩展,收缩或可忽略字符的传统排序规则,它只能在字符之间进行一对一比较。
如:
ß = s
对于utf8_general_ci是正确的
ß = ss
对于utf8_unicode_ci是正确的。
- 如果使用 utf8_unicode_ci 的排序不适用于某种语言,则 MySQL 将实现 utf8 语言特定的排序规则。例如,utf8_unicode_ci 适用于德语字典顺序和法语,因此无需创建特殊的 utf8 排序规则。
字符排序权重
字符的归类权重确定如下:
- 对于除“_bin”(二进制)排序规则外的所有 Unicode 归类,MySQL 执行 table 查找以查找字符的归类权重。
- 对于“_bin”排序规则,权重基于代码点,可能添加了前导零字节。
- 可以使用“WEIGHT_STRING()”函数显示整理权重。
如果排序规则使用权重查找 table,但是 table 中没有字符,则排序权重确定变得更加复杂:
- 对于一般排序规则(“xxx_general_ci”)中的 BMP 字符,权重是代码点。
- 对于 UCA 归类中的 BMP 字符(例如“xxx_unicode_ci”和特定于语言的排序规则),适用以下算法:
if (code >= 0x3400 && code <= 0x4DB5) base= 0xFB80; /* CJK Ideograph Extension */ else if (code >= 0x4E00 && code <= 0x9FA5) base= 0xFB40; /* CJK Ideograph */ else base= 0xFBC0; /* All other characters */ aaaa= base + (code >> 15); bbbb= (code & 0x7FFF) | 0x8000;
- 结果是两个整理元素的序列,aaaa后跟bbbb。例如:
mysql> SELECT HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)); +----------------------------------------------------------+ | HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)) | +----------------------------------------------------------+ | FBC084CF | +----------------------------------------------------------+
- 对于一般排序规则中的补充字符,权重是“0xfffd REPLACEMENT CHARACTER的权重”。对于 UCA 4.0.0 排序规则中的补充字符,其归类权重为“0xfffd”。也就是说,对于 MySQL,所有补充字符都彼此相等,并且几乎大于所有 BMP 字符。
- 所有补充字符都相等的规则不是最佳的,但是不会引起麻烦。这些字符非常少见,因此由多字符组成的字符串完全由补充字符组成非常罕见。如果您确实希望按 MySQL 规则对行进行排序,然后再按码点值对行进行排序,则很简单:
ORDER BY s1 COLLATE utf32_unicode_ci, s1 COLLATE utf32_bin
- 所有补充字符都相等的规则不是最佳的,但是不会引起麻烦。这些字符非常少见,因此由多字符组成的字符串完全由补充字符组成非常罕见。如果您确实希望按 MySQL 规则对行进行排序,然后再按码点值对行进行排序,则很简单:
- 对于基于高于 4.0.0 的 UCA 版本的补充字符,补充字符不一定都具有相同的整理重量(例如“xxx_unicode_520_ci”)。
其他信息
“xxx_general_mysql500_ci”排序规则保留原始“xxx_general_ci”排序规则在 5.1.24 之前的顺序,并允许对在 MySQL 5.1.24 之前创建的 table 进行升级(缺陷号 27877)。【???】