MySQL 启动时必须在 my.cnf 的 [mysqld] 段中同时设置 character_set_server=utf8mb4 和 collation_server=utf8mb4_unicode_ci,二者缺一不可,且需重启生效;运行时 SET GLOBAL 无效。

MySQL 启动时如何正确设置 collation_server
必须在 MySQL 启动前通过配置文件(my.cnf 或 my.ini)设置,运行时用 SET GLOBAL collation_server = 'utf8mb4_unicode_ci'; 无效 —— 这个变量是只读的,MySQL 8.0+ 尤其严格。
常见错误:改完配置没重启 mysqld,或者写在了错误 section(比如放在 [client] 下而不是 [mysqld])。
-
[mysqld]段下添加:collation_server = utf8mb4_unicode_ci - 配套必须设
character_set_server = utf8mb4,否则 collation 可能被强制降级 - 修改后用
mysql --verbose --help | grep "Default collation"验证是否生效(启动前),或连接后查SHOW VARIABLES LIKE 'collation_server';
新建数据库时默认排序规则从哪来?
不是只看 collation_server,而是由「服务器默认字符集 + 默认 collation 映射关系」共同决定。例如 character_set_server = utf8mb4 时,MySQL 会自动选该字符集下第一个可用的 collation(通常是 utf8mb4_0900_ai_ci,MySQL 8.0+ 默认;5.7 是 utf8mb4_general_ci)。
所以光设 collation_server 不设 character_set_server,可能被忽略。
- 显式建库时最好指定:
CREATE DATABASE db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 不指定则继承
character_set_server对应的默认 collation,不是collation_server的值 -
collation_server主要影响临时表、函数返回值、ORDER BY 等无显式 collation 上下文的场景
ALTER DATABASE 修改默认 collation 会影响已有表吗?
不会。只改变该库后续新建表的默认 collation,已有表的列定义、索引排序规则全部保持不变。
典型误操作:以为改了库级 collation 就能统一排序行为,结果 SELECT ... ORDER BY name 仍按老 collation 排序,因为字段本身定义没变。
- 已有列需单独改:
ALTER TABLE t1 MODIFY name VARCHAR(100) COLLATE utf8mb4_unicode_ci; - 如果列上有索引,MODIFY 可能触发重建,注意锁和性能
- 检查当前列 collation:
SHOW FULL COLUMNS FROM t1;看Collation列
为什么 utf8mb4_unicode_ci 和 utf8mb4_0900_ai_ci 排序结果不同?
这是 MySQL 8.0 引入的新 collation,基于 Unicode 9.0 标准,对重音、大小写、变音符号的处理更精确。旧的 utf8mb4_unicode_ci 基于较老的 UCA 算法,排序和比较逻辑有差异 —— 比如德语 ä 在新 collation 中等价于 ae,旧版可能只当 a 处理。
升级后发现 ORDER BY 或 WHERE 匹配行为突变,大概率是这个原因。
- 应用依赖特定排序逻辑时,不要盲目切到
0900_ai_ci - 跨版本迁移需测试字符串比较、GROUP BY、UNION 等场景
- 若需兼容旧行为,可显式指定 collation:
ORDER BY name COLLATE utf8mb4_unicode_ci
SELECT COLLATION('abc') 和 SELECT @@collation_database 往往比瞎改 my.cnf 更快定位问题。


















