utf8 与 utf8mb4 的区别及迁移注意事项
该文章由AI生成,仅为SEO优化测试,相关内容不保证准确!!!
引言
MySQL 的 utf8 编码有个历史遗留问题:它最多只支持 3 字节字符,而真正的 UTF-8 最长 4 字节。这意味着 emoji(😊)、部分生僻汉字、某些数学符号都无法存储——写入直接报错或变成问号。解决方案是把字符集换成 utf8mb4。
一、为什么要换 utf8mb4
utf8mb4 才是完整的 UTF-8 实现,最多 4 字节,完整覆盖 emoji、Unicode 增补平面字符。用户昵称、评论里出现 emoji 已经是常态,新闻、商品描述里也可能包含生僻字。凡是涉及用户生成内容(UGC)的表,都应使用 utf8mb4。另一个考虑:MySQL 8.0 的默认字符集已经是 utf8mb4,新项目直接用 8.0 可以省去迁移。
二、迁移改造步骤
改造涉及四层:① 表与列:ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(注意:会重建表与索引,大表要在低峰执行并评估空间);② 库默认字符集:ALTER DATABASE db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(只影响新建表);③ 连接层:应用连接串加 charset=utf8mb4(PHP PDO 在 DSN 里指定;JDBC 用 characterEncoding=UTF-8),连接后执行 SET NAMES utf8mb4 也可以;④ my.cnf:[mysqld] 段设 character-set-server=utf8mb4、collation-server=utf8mb4_unicode_ci,避免新建表又回到 utf8。
三、迁移的坑
① 索引长度限制:utf8mb4 下每字符最多 4 字节,varchar(255) 的索引需要 255×4=1020 字节,超过 InnoDB 默认 767 字节限制(老版本)会报错——开启 innodb_large_prefix 或使用 DYNAMIC 行格式(8.0 默认)即可,且索引长度上限变为 3072 字节。② 空间占用:中文在 utf8mb4 下仍为 3 字节,纯 ASCII 场景实际仍 1 字节(varchar 是变长存储),空间影响比想象的小。③ 排序规则选择:utf8mb4_general_ci 快但不够精确(某些字符比较相等),utf8mb4_unicode_ci 更准确,8.0 推荐 utf8mb4_0900_ai_ci。已有数据混用时统一即可。④ 迁移前备份:CONVERT TO 会重建表,务必先备份;转换后用应用实测 emoji 存取。
总结
utf8mb4 不是可选项而是必选项——只要业务涉及用户内容。迁移四层同步改:表/列、库默认、连接串、服务端默认;关注索引长度与排序规则选择,迁移前备份、迁移后实测 emoji。新项目直接上 MySQL 8.0 + utf8mb4,一步到位。