插件窝 干货文章 MySQL 中的 UTF8MB4 是定长存储吗?

MySQL 中的 UTF8MB4 是定长存储吗?

字节 字符 存储 UTF8MB4 317    来源:    2025-03-30

MySQL 中 UTF8MB4 的存储特性分析

UTF8MB4 在 MySQL 中不是完全的定长存储,它是一种可变长度(变长)的字符编码。以下是详细分析:

存储特性

  1. 变长编码: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)
  2. 与 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字节

性能考虑

  1. 索引长度限制

    • InnoDB 索引最大长度 767 字节(默认)
    • 对于 utf8mb4,一个索引列最多能包含约 191 个字符 (767÷4≈191)
  2. 排序规则

    • utf8mb4 有多种排序规则可选(如 utf8mb4_general_ci, utf8mb4_unicode_ci)
    • 不同排序规则对性能和准确性有不同影响

最佳实践建议

  1. 现代应用应优先使用 utf8mb4 而非 utf8
  2. 对于已知只包含 ASCII 或 BMP 字符的列,可以考虑使用 utf8mb3 节省空间
  3. 设计表结构时需考虑字符集对索引长度的影响

如需完全的定长存储,可以考虑使用 utf8mb4 的 CHAR 类型,但会浪费存储空间。