MariaDB 10.2中utf8_spanish2_ci排序规则是否正常工作?
为啥MariaDB 10.2里utf8_spanish2_ci排序和预期不一样?
刚照着《MySQL Cookbook》第3版的例子测试时,我也碰到了这个困惑:明明代码没问题,结果却和书里说的不一样。先把场景还原一下:
测试代码(来自《MySQL Cookbook》第3版)
CREATE TABLE t (c CHAR(2) CHARACTER SET utf8); INSERT INTO t (c) VALUES('cg'),('ch'),('ci'),('lk'),('ll'),('lm');
预期vs实际结果
- 执行
SELECT c FROM t ORDER BY c COLLATE utf8_general_ci;,结果符合预期:cg, ch, ci, lk, ll, lm - 按照书中描述,用
utf8_spanish2_ci排序应该得到cg, ci, ch, lk, lm, ll(西班牙语规则里ch是单独的排序单元,ll要排在lm后面),但MariaDB 10.2里跑出来的结果和utf8_general_ci完全一致。
问题出在哪?
核心原因是MariaDB 10.2及更早版本对utf8字符集的utf8_spanish2_ci实现有差异:
- 在原生MySQL里,
utf8(实际是utf8mb3)的utf8_spanish2_ci会把ch、ll当作单个排序单元处理,所以排序逻辑符合西班牙语规则。 - 但MariaDB 10.2里的
utf8版utf8_spanish2_ci并没有启用这个特性,自然就和通用排序规则结果一样了。
怎么解决?
有两个简单的办法能拿到书里的预期结果:
方法1:换成utf8mb4字符集
不管MariaDB版本是啥,utf8mb4_spanish2_ci都能正确处理西班牙语的特殊排序规则。可以直接修改表结构,或者查询时临时转码:
-- 方案A:修改表的字符集 ALTER TABLE t MODIFY COLUMN c CHAR(2) CHARACTER SET utf8mb4; SELECT c FROM t ORDER BY c COLLATE utf8mb4_spanish2_ci; -- 方案B:查询临时转码,无需改表 SELECT c FROM t ORDER BY CONVERT(c USING utf8mb4) COLLATE utf8mb4_spanish2_ci;
执行后就能得到预期结果:cg, ci, ch, lk, lm, ll
方法2:升级MariaDB到10.3+
MariaDB 10.3及之后的版本,已经修复了utf8字符集下utf8_spanish2_ci的排序问题,升级后直接跑原来的查询就能得到预期结果。
额外提一句
书里的测试是基于MySQL环境,MariaDB作为分支版本,部分字符集排序规则的实现和原生MySQL存在差异很正常。而且
utf8mb4本身就是更推荐的字符集,它支持完整的Unicode字符(比如emoji),比老的utf8(utf8mb3)实用多了。
内容的提问来源于stack exchange,提问作者grjash
相关产品推荐
相关产品推荐

