MySQL 中的 UTF8MB4 是定长存储吗?
MySQL 中 UTF8MB4 的存储特性分析
UTF8MB4 在 MySQL 中不是完全的定长存储,它是一种可变长度(变长)的字符编码。以下是详细分析:
存储特性
变长编码:UTF8MB4 是 UTF-8 编码的实现,使用 1-4 个字节存储每个字符
- 1字节:ASCII 字符 (U+0000 到 U+007F)
- 2字节:大部分拉丁字母和符号 (U+0080 到 U+07FF)
- 3字节:基本多文种平面 (BMP) 中的字符 (U+0800 到 U+FFFF)
- 4字节:补充字符 (如表情符号,U+10000 到 U+10FFFF)
与 UTF8 的区别:
- MySQL 的
utf8
实际上是阉割版,只支持最多3字节
utf8mb4
才是完整的 UTF-8 实现,支持4字节字符
对存储空间的影响
CHAR 类型:会保留声明长度的空间(定长)
CHAR(10) CHARACTER SET utf8mb4
无论存储什么字符都会占用 10×4=40 字节(最坏情况)
VARCHAR 类型:按实际字符长度存储(变长)
VARCHAR(10) CHARACTER SET utf8mb4
存储 ASCII 字符只需 10×1+长度标记=11~12字节
存储4字节字符最多需要 10×4+长度标记=41~42字节
性能考虑
索引长度限制:
- InnoDB 索引最大长度 767 字节(默认)
- 对于 utf8mb4,一个索引列最多能包含约 191 个字符 (767÷4≈191)
排序规则:
- utf8mb4 有多种排序规则可选(如 utf8mb4_general_ci, utf8mb4_unicode_ci)
- 不同排序规则对性能和准确性有不同影响
最佳实践建议
- 现代应用应优先使用 utf8mb4 而非 utf8
- 对于已知只包含 ASCII 或 BMP 字符的列,可以考虑使用 utf8mb3 节省空间
- 设计表结构时需考虑字符集对索引长度的影响
如需完全的定长存储,可以考虑使用 utf8mb4 的 CHAR 类型,但会浪费存储空间。