MySQL 8.0 已弃用 utf8mb4_general_ci,新项目应使用 utf8mb4_0900_as_cs 或 utf8mb4_0900_ai_ci;前者区分大小写和重音,适用于登录名等精确匹配场景,后者不区分,适用于搜索等模糊匹配场景。

utf8mb4_general_ci 已被 MySQL 8.0 弃用,别再新项目里用它
MySQL 官方从 8.0 开始把 utf8mb4_general_ci 标记为 deprecated,后续版本会彻底移除。它不支持 Unicode 9.0+ 的排序规则(比如越南语重音、德语 ß 转换),连基本的大小写等价都靠查表硬凑,性能差还容易出错。
常见错误现象:SELECT 'ß' = 'SS' COLLATE utf8mb4_general_ci 返回 1(错误),而实际德语中 ß 等价于 ss,但该 collation 并未按标准实现;ORDER BY 对 emoji 或中文混合排序结果混乱。
- 新项目一律用
utf8mb4_0900_as_cs(区分大小写、区分重音)或utf8mb4_0900_ai_ci(不区分大小写、不区分重音) - 如果必须兼容老应用且不能改逻辑,可暂时保留
utf8mb4_general_ci,但禁止在 WHERE / ORDER BY 中依赖其“智能”行为 -
utf8mb4_unicode_ci是 5.7 时代的过渡方案,也已过时,不要选
utf8mb4_0900_ai_ci 和 utf8mb4_0900_as_cs 怎么选
核心区别就两点:是否区分大小写(case)、是否区分重音(accent)。_ai_ci 是 “accent insensitive, case insensitive”,_as_cs 是 “accent sensitive, case sensitive”。
使用场景:
- 用户登录名、邮箱字段建议用
utf8mb4_0900_as_cs—— 避免 'Admin' 和 'admin' 被当成同一账号 - 文章标题、评论内容常用
utf8mb4_0900_ai_ci—— 搜索“cafe”能匹配到“café”,更符合用户直觉 - 密码哈希值、token 字段必须用二进制 collation(如
utf8mb4_bin),否则可能因 collation 规则导致校验失败
性能影响很小,两者底层都基于 UCA 9.0.0,索引效率几乎一致;但 _as_cs 在比较时少一次 Unicode 归一化步骤,理论快一点点。
建表时指定 collation 的实操要点
别只改数据库或列的字符集,collation 必须显式声明,否则可能继承 server 默认(而 server 默认可能是 utf8mb4_general_ci)。
正确做法:
- 创建库时加
DEFAULT COLLATE utf8mb4_0900_ai_ci - 建表时每列单独指定:
title VARCHAR(255) COLLATE utf8mb4_0900_ai_ci - 临时改某次查询行为:
SELECT * FROM posts WHERE title = 'hello' COLLATE utf8mb4_0900_as_cs
容易踩的坑:ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 不会自动升级 collation,只会变成 utf8mb4_general_ci(如果 server 是旧版);必须补上 COLLATE utf8mb4_0900_ai_ci。
已有数据迁移到新 collation 会丢数据吗
不会丢数据,但可能触发隐式转换警告或报错,尤其是字段含非法 UTF-8 字节(比如从 latin1 直接转 utf8mb4 未清理脏数据)。
安全迁移步骤:
- 先用
SHOW CREATE TABLE t确认当前 collation - 备份后执行:
ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci - 如果报
ERROR 1815 (HY000),说明有索引长度超限(utf8mb4 下单字符最多 4 字节,原前缀索引可能不够),需调大innodb_large_prefix或缩短索引长度
真正麻烦的是应用层 —— 比如 PHP 的 mysql_real_escape_string()(已废弃)或某些 ORM 对 collation 敏感的缓存键生成逻辑,这些地方往往被忽略。


















