是。MySQL 8.0 默认改用严格区分大小写和重音的 utf8mb4_0900_as_cs 排序规则,导致 ORDER BY 等行为变化;需逐层检查并按需统一 collation,不可仅靠配置文件一劳永逸。

MySQL 8.0 升级后 ORDER BY 结果乱了,是不是 utf8mb4_0900_as_cs 搞的?
是。MySQL 8.0 默认将 collation_server 和新建库/表的默认排序规则(Collation)从 utf8mb4_general_ci 或 utf8mb4_unicode_ci 切换为更严格、区分大小写和重音的 utf8mb4_0900_as_cs。它影响 ORDER BY、GROUP BY、= 比较甚至索引合并行为——不是“错”,而是“变严格”了。
实操建议:
- 先确认当前行为:执行
SELECT @@collation_server, @@collation_database;;查表级 collation 用SHOW CREATE TABLE `your_table`; - 若只需临时兼容旧逻辑,可在查询中显式指定:
SELECT * FROM users ORDER BY name COLLATE utf8mb4_unicode_ci; - 不建议全局改回旧 collation(如
utf8mb4_unicode_ci),因为会削弱字符处理准确性,且新版本已逐步弃用部分旧规则
升级后应用报 Illegal mix of collations 错误怎么办?
这是最典型的升级踩坑点:不同字段或表达式用了不兼容的 collation(比如一个字段是 utf8mb4_0900_as_cs,另一个是 utf8mb4_unicode_ci),MySQL 拒绝隐式转换。
常见触发场景:
-
JOIN时 ON 条件两边 collation 不一致 -
UNION查询中列的 collation 不统一 - 函数返回值(如
CONCAT()、UPPER())与字段 collation 冲突
解决优先级:先定位,再收敛。用 SHOW FULL COLUMNS FROM table_name; 查各字段 collation;对 JOIN/UNION 中涉及字段,统一显式加 COLLATE utf8mb4_0900_as_cs(推荐)或批量修改字段 collation:
ALTER TABLE users MODIFY name VARCHAR(255) COLLATE utf8mb4_0900_as_cs;
要不要把所有表都改成 utf8mb4_0900_as_cs?
不能一刀切。新 collation 更精确,但代价是性能略降(尤其大量字符串比较)、部分业务逻辑可能意外变更(比如之前 'a' = 'A' 返回 TRUE,现在默认 FALSE)。
判断依据看实际需求:
- 用户昵称、评论等需大小写不敏感搜索 → 保留
utf8mb4_0900_as_cs+ 在查询中用LOWER()或建函数索引 - 密码哈希、token、唯一标识类字段 → 必须用
_as_cs,避免因 collation 导致重复插入失败 - 历史遗留系统且无资源重测 → 可只对新表/新字段启用,老表维持原 collation,通过连接层或 SQL 层做 collation 对齐
注意:ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs 会重写整表,锁表时间长,线上慎用。
配置文件里改 collation-server 就能一劳永逸?
不能。设了 collation-server 只影响新创建的数据库默认 collation,已有库、表、字段完全不受影响;而且 MySQL 启动时若发现配置与数据字典不一致(比如表定义是 utf8mb4_unicode_ci,但 server 是 utf8mb4_0900_as_cs),也不会自动修正。
真正要改的配置项(需重启生效):
collation-server = utf8mb4_0900_as_cscharacter-set-server = utf8mb4- 必须同时配
init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_0900_as_cs'(仅限非 SUPER 用户连接生效)
但配置只是起点。真正的落地在数据层:每个库、每张表、每个关键字段的 collation 都得按需检查和调整,漏掉一个就可能在某个 JOIN 或 ORDER BY 里突然冒出来。


















