MySQL 中 utf8 和 utf8mb4 有什么区别?
MySQL 中 utf8 和 utf8mb4 有什么区别?
字符编码 是现代应用程序和 hosting environments 中数据存储、查询和呈现的基础。如果你在由 MySQL 或 MariaDB 支持的 shared hosting、VPS 或 dedicated server 上运行网站或 web application,你很可能遇到过 utf8 和 utf8mb4 这两个术语。乍一看,它们似乎是同义词——都表示 Unicode 编码。但在底层,它们有一个关键区别,这个区别可能决定你的 app 能否存储现代文本数据,如 emoji、多语言内容或某些 CJK(中文、日文、韩文)字符——尤其是在国际化或 multilingual hosting solutions 中。

定义
utf8
utf8MySQL 的 legacy Unicode encoding。
支持 only 3 bytes per character。
能够存储 Basic Multilingual Plane (BMP) 中的字符:U+0000 到 U+FFFF。
Cannot store emoji、音乐符号、某些中文字符以及其他补充字符。
utf8mb4
utf8mb4(Multi-Byte 4)
真正的 real UTF-8 实现。
支持 full Unicode,包括 BMP 之外的字符。
最多使用 4 bytes per character——这正是 UTF-8 的设计方式。
存储 emoji (😊)、罕见中文字符 (𠀋) 或数学符号 (𝛑) 所必需。
MySQL 中具有误导性的 utf8
在 MySQL 中,utf8 字符集 not a full implementation of the UTF-8 standard。它 limited to 3 bytes,而标准 UTF-8 最多使用 4 bytes。这意味着:
MySQL 中的 utf8 is not real UTF-8。
它更像是 UTF-8 的一个 subset,排除了 U+FFFF 之外的码位。
相比之下,utf8mb4 完全符合 UTF-8 标准。
技术对比
| Feature | utf8 | utf8mb4 |
|---|---|---|
| 每个字符的最大 bytes | 3 | 4 |
| Unicode 覆盖范围 | Up to U+FFFF (BMP only) | Full range (up to U+10FFFF) |
| Emoji 支持 | ❌ No | ✅ Yes |
| 补充字符支持 | ❌ No | ✅ Yes |
| MySQL 兼容性 | ✅ Legacy-safe | ✅ Full Unicode |
| Collation options | Limited | More extensive (e.g., utf8mb4_0900_ai_ci) |
为什么 utf8mb4 是正确选择
1. Emoji and Modern Symbol Support
你无法使用 MySQL 的 utf8 存储 🐱、🧠、🚀 或 🇩🇪。这些都超出了 BMP。
2. 更好的 Collation 和排序
utf8mb4 支持更新的 collation,例如:
utf8mb4_unicode_ci: Unicode standard sorting
utf8mb4_general_ci: Fast but less accurate
utf8mb4_0900_ai_ci: Modern Unicode 9.0-aware collation (available in MySQL 8+)
3. 面向未来
随着 Unicode 的扩展,新字符将落在 3-byte 范围之外。utf8mb4 可确保你不会被未来的符号所限制。
如果使用 utf8 会发生什么?
如果你尝试将一个 4-byte 字符(如 emoji)插入到一个 column with+ 中,你会得到这个错误:
ERROR 1366 (HY000): Incorrect string value: 'xF0x9Fx98x81' for column 'title' at row 1更糟的是,如果没有正确验证,你的 app 可能会悄悄地 truncate or corrupt data。
从 utf8 迁移到 utf8mb4
要安全地迁移你的 schema:
步骤 1:更新 table 和 column 定义
ALTER TABLE my_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;步骤 2:更新 database 默认值
ALTER DATABASE my_db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;步骤 3:更新 application connection settings
确保你的 app 使用 utf8mb4 连接:
SET NAMES utf8mb4;最佳实践
✅ Always use utf8mb4 用于新数据库。
✅ 使用 utf8mb4_unicode_ci 以获得准确性,或使用 utf8mb4_general_ci 以获得性能。
✅ 在 table 和 database 级别设置默认 charset。
✅ 确保 application-layer libraries(例如 PDO、MySQLi、Sequelize)支持 utf8mb4。
结论
MySQL 中 utf8 和 utf8mb4 的区别不只是一个 byte——它是现代 Unicode 兼容性与静默失败之间的区别。虽然 utf8 仍然向后兼容,但在许多现代用例中它已被弃用。始终优先使用 utf8mb4,以使你的 application 面向未来,并确保完整的多语言、emoji 和特殊符号支持。


