直接修改 collation_server 无法解决已有表的字符集冲突,必须逐字段确认并修改真实 collation;否则 join、find_in_set、json_value 等操作仍报 illegal mix of collations。

直接改 collation_server 配置不能解决已有表的字符集冲突,必须逐字段确认并修改真实 collation;否则 JOIN、FIND_IN_SET、JSON_VALUE 等操作仍会报 Illegal mix of collations。
查清表和字段的真实 collation 是第一步
错误不是配置错,而是 5.7 旧表用 utf8mb4_general_ci,8.0 新表默认用 utf8mb4_0900_ai_ci,两者在比较时无法隐式转换。你得看实际定义,不是看注释或默认值:
- 执行
SHOW FULL COLUMNS FROM your_table;,检查每列的Collation值(这是真实生效的) - 执行
SHOW CREATE TABLE your_table;,确认表级COLLATE和字段是否显式声明——没写的字段会继承表级规则,但表级本身可能也没写,最终 fallback 到服务器默认值 - 特别注意
FIND_IN_SET()、UNION、JOIN ON这类操作:它们直接拿字段 collation 比较,不走collation_server
ALTER TABLE 修改字段 collation 是唯一治本动作
临时在 SQL 里加 COLLATE utf8mb4_0900_ai_ci 只能绕过单条语句,不能修复数据层不一致。批量统一必须落到字段定义上:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- 用
ALTER TABLE t MODIFY col VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;替换旧 collation - 如果字段是索引前缀(比如
VARCHAR(500)但只索引前 191 字符),要检查长度是否超限:utf8mb4_0900_ai_ci的索引长度计算更严格,可能需调小前缀长度 - 别漏掉
TEXT类型字段——它们也能带 collation,且同样参与比较
FIND_IN_SET 和 JSON_VALUE 必须显式统一 collation
MySQL 8.0 对隐式转换更保守,宁可报错也不静默降级:
-
FIND_IN_SET(col1 COLLATE utf8mb4_0900_ai_ci, @var COLLATE utf8mb4_0900_ai_ci)—— 两个参数都得显式指定 - 虚拟列 + 索引写法已失效,必须改用
CREATE INDEX idx ON t (JSON_VALUE(data, '$.field' RETURNING CHAR(100) COLLATE utf8mb4_0900_ai_ci)) -
SHOW CREATE TABLE输出里的 collation 注释可能带utf8mb4_0900_ai_ci,但字段定义里没写,这属于干扰项,只认白纸黑字写的那部分
最容易被跳过的其实是字段定义里没显式声明 collation,却依赖服务器默认值——升级后新连接用 utf8mb4_0900_ai_ci,老连接或旧表仍用 utf8mb4_general_ci,这种“隐形不一致”会在 JOIN 或 WHERE 条件里突然爆发。










