mysql 8.0 中 set global collation_server 无效,因其不决定新建库/表默认排序规则;实际由 character_set_server 硬编码绑定默认 collation(如 utf8mb4 → utf8mb4_0900_ai_ci),collation_server 仅作连接初始化参考。

改 collation-server 参数本身在 MySQL 8.0 中基本无效——它不会改变新建库/表的默认排序规则,也不会修复已有对象的行为。
为什么 set global collation_server = utf8mb4_unicode_ci 没用?
MySQL 8.0 起,collation-server 不再决定新建数据库或表的默认 COLLATE。系统会根据 character_set_server 自动绑定一个“默认 collation”:比如 character_set_server = utf8mb4 时,哪怕你显式设了 collation-server = utf8mb4_unicode_ci,实际新建库仍用 utf8mb4_0900_ai_ci。
这个映射关系是硬编码的,无法通过配置覆盖。
-
SHOW VARIABLES LIKE 'collation%';看到的collation_server值,只是连接初始化时的参考,不参与对象创建逻辑 -
CREATE DATABASE db1;的实际排序规则,取决于character_set_server对应的默认 collation,不是collation_server - 修改该变量后重启,
SHOW CREATE DATABASE db1;依然显示COLLATE=utf8mb4_0900_ai_ci
真正影响新建对象默认排序规则的是什么?
只有 character_set_server 的值起决定性作用,且其绑定的默认 collation 是固定的:
-
character_set_server = utf8mb4→ 默认COLLATE = utf8mb4_0900_ai_ci(MySQL 8.0+ 行为) -
character_set_server = latin1→ 默认COLLATE = latin1_swedish_ci - 没有配置项能“把 utf8mb4 的默认 collation 改成 utf8mb4_unicode_ci”
想让新库默认用 utf8mb4_unicode_ci,唯一办法是不用 utf8mb4 作为服务器字符集——但这不现实,也不推荐。
遇到 Illegal mix of collations 错误时,别碰 collation-server
这类报错(如 ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT))根本原因是字段、表达式或连接条件中混用了不同 collation,和 collation-server 无关。
- 查问题字段:
SHOW FULL COLUMNS FROM table_name;看Collation列 - 临时修复查询:
WHERE col1 = col2 COLLATE utf8mb4_0900_ai_ci或统一加COLLATE utf8mb4_0900_ai_ci - 长期解法:批量修正字段定义,例如
ALTER TABLE t MODIFY c VARCHAR(100) COLLATE utf8mb4_0900_ai_ci; - 不要试图用
init-file执行SET GLOBAL collation_connection来“兜底”,这解决不了 JOIN 或函数内部的 collation 冲突
真正需要改的三个层级,顺序不能错
升级后要统一排序行为,必须按数据库 → 表 → 字段三级推进,collation-server 不在此列:
- 改库级默认:
ALTER DATABASE `db_name` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; - 改表结构(含字段):
ALTER TABLE `t` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;(注意是CONVERT TO,不是CHARACTER SET = ...) - 单独修字段(如果之前被显式指定过旧 collation):
ALTER TABLE `t` MODIFY `c` TEXT COLLATE utf8mb4_0900_ai_ci;
漏掉任何一层,都可能在某次 JOIN 或子查询里突然触发 Illegal mix。尤其注意 CONVERT TO 不会覆盖字段级显式声明的 collation,那种字段必须单独 MODIFY。











