MySQL中修改字段校对规则必须用MODIFY(或CHANGE)并重复完整类型定义,如ALTER TABLE users MODIFY name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;仅写COLLATE会报语法错误。

ALTER TABLE MODIFY COLUMN 必须带完整类型定义
直接用 ALTER TABLE ... COLLATE 只改表级默认值,对已有字段无效。想改某个 VARCHAR 或 TEXT 字段的校对规则,必须用 MODIFY(或 CHANGE),且要重复写一遍字段类型声明。
常见错误是只写:ALTER TABLE users MODIFY name COLLATE utf8mb4_unicode_ci —— 这会报语法错误,因为 MySQL 要求你明确字段类型。
- 正确写法:
ALTER TABLE users MODIFY name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci - 如果原字段允许 NULL,记得补上
NULL或NOT NULL,否则可能意外变成 NOT NULL - TEXT 类型不能指定长度,得写成
TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
UNION / JOIN 出现 1271 错误时优先用 CONVERT() 临时对齐
当两个表字段 collation 不一致导致 Illegal mix of collations(错误 1271),别急着改表结构——尤其在线上大表。
在查询里显式转换更安全、更快:
SELECT CONVERT(title USING utf8mb4) COLLATE utf8mb4_unicode_ci AS title FROM table_a- UNION 时所有子查询都套一层
CONVERT(... COLLATE ...),确保输出列 collation 一致 - JOIN 条件中也适用:
ON a.name COLLATE utf8mb4_unicode_ci = b.name COLLATE utf8mb4_unicode_ci
注意:CONVERT(col USING charset) 会隐式使用该 charset 的默认 collation;加 COLLATE 才能精确控制。
MySQL 数据库管理技能,能够通过自然语言查询和管理数据库,支持 SELECT/INSERT/UPDATE/DELETE、表管理、备份恢复等操作。当用户提及 MySQL、数据库查询、建表或数据备份时使用此技能。
utf8mb4_unicode_ci 和 utf8mb4_0900_ai_ci 的实际差异不能忽略
MySQL 8.0 默认用 utf8mb4_0900_ai_ci,它比 utf8mb4_unicode_ci 更准:支持重音不敏感(ai)、大小写不敏感(ci),且按 Unicode 14.0 排序。但两者不兼容——混用会直接触发错误 1267。
- 查当前字段用的哪个:
SELECT COLUMN_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME = 'name' - 新建表建议统一用
utf8mb4_0900_ai_ci(MySQL 8.0+)或utf8mb4_unicode_ci(兼容老版本) - 升级到 8.0 后,旧表不会自动改 collation,得手动跑
ALTER TABLE ... CONVERT TO...
建表时没写 COLLATE,后续就容易掉坑里
很多人建表只写 DEFAULT CHARSET=utf8mb4,以为万事大吉。其实字段级 collation 是继承来的,而继承链有三层:连接层 → 库级 → 表级 → 列级。只要其中某一级变了,新字段就可能和老字段不一致。
- 最稳妥的写法:每个字符字段都显式声明
COLLATE,例如name VARCHAR(50) COLLATE utf8mb4_0900_ai_ci - 不要依赖
collation_connection,它受客户端连接参数影响(比如 JDBC URL 漏了connectionCollation就会退回到utf8mb4_general_ci) - 线上排查时,优先看
SHOW VARIABLES LIKE '%coll%'和SHOW CREATE TABLE对照,而不是只信文档里的“默认值”
真正麻烦的不是改一次 collation,而是改完后 order by、group by、索引范围扫描的结果都可能变——这些逻辑往往藏在业务代码深处,测试容易漏。










