MySQL 排序规则迁移:utf8mb4_0900_ai_ci、89 种 collation 与 5.7 回导报错
排序规则命名约定
排序规则名以字符集名开头,后跟表示特征的后缀。utf8mb4_0900_ai_ci、latin1_swedish_ci 分别是 utf8mb4 和 latin1 的排序规则。binary 字符集只有一个排序规则 binary,没有后缀。
| 后缀 | 意义 |
|---|---|
| _ai | 不区分重音(accent insensitive) |
| _as | 区分重音 |
| _ci | 不区分大小写 |
| _cs | 区分大小写 |
| _ks | 区分假名 |
| _bin | 二进制 |
对不指定重音敏感性的非二进制排序规则,由大小写敏感性决定:不含 _ai/_as 时,_ci 隐含 _ai,_cs 隐含 _as。也就是 latin1_general_ci = 不区分大小写 + 隐含不区分重音;latin1_general_cs = 区分大小写 + 隐含区分重音;utf8mb4_0900_ai_ci = 显式不区分大小写且不区分重音。
Unicode 字符集的排序规则名可能含版本号,表示基于哪个 Unicode Collation Algorithm(UCA)版本:
- utf8mb4_0900_ai_ci 基于 UCA 9.0.0
- utf8mb4_unicode_520_ci 基于 UCA 5.2.0
- utf8mb4_unicode_ci(无版本号)基于 UCA 4.0.0
- xxx_general_mysql500_ci 保留 5.1.24 之前的排序,允许升级 5.1.24 前建的表(Bug #27877)
binary 排序规则按字节值比较;_bin 排序规则按字符代码值比较(多字节字符不等于字节值)。
默认排序规则的变化
- MySQL 5.7:utf8mb4 默认 utf8mb4_general_ci
- MySQL 8.0:utf8mb4 默认 utf8mb4_0900_ai_ci
执行 SHOW COLLATION WHERE Charset='utf8mb4';,8.0 下 utf8mb4 排序规则有 89 种,5.7 只有 26 种,多出的 63 种都带 0900 标识。utf8mb4_0900_ai_ci 在 5.7 中不存在——把 8.0 建的表导回 5.7/5.6,会因字符集/排序规则无法识别而报错。
相关参数:
- collation_server:服务器级默认排序规则
- 未指定 collation_database 时默认继承 collation_server
- 建库未指定排序规则时用 collation_database
- character_set_database / collation_database 在 5.7 被弃用
- default_collation_for_utf8mb4:控制 utf8mb4 默认排序规则,取值 utf8mb4_0900_ai_ci 或 utf8mb4_general_ci;在 SHOW COLLATION/CHARACTER SET、建库/改库/建表/改表/加列/改列指定 utf8mb4 但未指定排序规则时生效
utf8mb4_0900_ai_ci 与 utf8mb4_general_ci 对比
| 特性 | utf8mb4_0900_ai_ci | utf8mb4_general_ci |
|---|---|---|
| Unicode 标准 | 基于 UCA 9.0.0 | 简化规则,未严格遵循 Unicode |
| 准确性 | 更高,支持现代语言、emoji、特殊字符 | 较低,部分字符排序不符预期 |
| 性能 | 现代硬件差异可忽略 | 旧算法可能稍快 |
| 兼容性 | MySQL 8.0+ 默认 | 旧版本默认,兼容更广 |
| 重音/大小写 | 忽略重音 + 忽略大小写 | 仅忽略大小写 |
比较行为的差异可以直接用 SQL 验证:
-- utf8mb4_general_ci:'ä' 可能被当作 'a'
SELECT 'ä' COLLATE utf8mb4_0900_ai_ci = 'a'; -- 返回 0(不相等)
SELECT 'ä' COLLATE utf8mb4_general_ci = 'a'; -- 可能返回 1(相等)
-- 长度/末尾空格:utf8mb4_0900_ai_ci 为 NO PAD,不忽略末尾空格
带 0900 的排序规则 Pad_attribute 为 NO PAD,'abc ' 与 'abc' 不相等;utf8mb4_general_ci 是 PAD SPACE,'abc ' 与 'abc' 相等。
选型与注意事项
优先 utf8mb4_0900_ai_ci:新项目、多语言(德语变音符号、西里尔、中日韩、emoji)、希望跟随官方推荐。
沿用 utf8mb4_general_ci:旧系统升级、已有数据依赖旧排序规则、无法承受迁移风险。
注意:修改排序规则可能触发索引重建,并影响 WHERE、ORDER BY 结果;升级前先在测试环境验证;应用层(Hibernate、SQLAlchemy 等)与数据库排序规则保持一致。