MySQL utf8 和 utf8mb4 的区别

字符集、校对规则和 Unicode

字符集 (Character Sets) 是指一种从二进制编码到某类字符符号的映射,可以参考如何使用一个字节来表示英文字母。

“校对” (Collations) 是指一组用于某个字符集的排序规则。

MySQL 服务器有默认的字符集和校对规则,每个数据库也有自己的默认值,每个表也有自己的默认值。这是一个逐层继承的默认设置,最终最靠底层的默认设置将影响你创建的对象。这些默认值,至上而下地告诉 MySQL 应该使用什么字符集来存储某个列。

MySQL 8.0 默认服务端字符集和校对规则分别为 utf8mb4utf8mb4_0900_ai_ci

MySQL 5.6/5.7 默认服务端字符集和校对规则分别为 latin1latin1_swedish_ci

使用命令 SHOW CHARACTERSETSHOW COLLATION 来查看 MySQL 支持的字符集和校对规则。

可通过查询环境变量查看当前版本信息:SHOW VARIABLES Like '%character_set%';

更多介绍查看官方文档

Unicode 支持

Unicode 标准包括来自基本多文种平面 (BMP) 的字符和位于 BMP 之外的补充字符。本节介绍 MySQL 中对 Unicode 的支持。有关 Unicode 标准本身的信息,请访问 Unicode 联盟网站

BMP 字符具有以下特征:

  • 它们的码点值 (code point values) 在 0 到 65535 之间 (U+0000 和 U+FFFF)。
  • 它们可以使用 8 位,16 位或 24 位(1 到 3 个字节)以可变长度编码进行编码。
  • 它们可以使用 16 位(2 字节)以固定长度编码进行编码。
  • 它们足以应付主要语言中的几乎所有字符。

补充字符位于 BMP 之外:

  • 它们的码点值在 U+10000 和 U+10FFFF 之间,主要是一些 emoji 表情。
  • Unicode 对补充字符的支持要求字符集的范围超出了 BMP 字符,因此比 BMP 字符占用更多的空间(每个字符最多 4 个字节)。

根据 RFC 3629 实现了用于对 Unicode 数据进行编码的 UTF-8(具有 8 位单位的 Unicode 转换格式)方法,该方法描述了从一到四个字节的编码序列。 UTF-8 的思想是使用不同长度的字节序列对各种 Unicode 字符进行编码:

  • 基本的拉丁字母,数字和标点符号使用一个字节。
  • 大多数欧洲和中东脚本字母均以 2 字节的顺序排列:扩展的拉丁字母(带有波浪号,长音符号,重音和其他重音符号),西里尔字母,希腊语,亚美尼亚语,希伯来语,阿拉伯语,叙利亚语等。
  • 韩文,中文和日文表意文字使用 3 字节或 4 字节序列。

MySQL 支持以下 Unicode 字符集:

  • utf8mb4: Unicode 字符集的 UTF-8 编码,每个字符使用一到四个字节。
  • utf8mb3: Unicode 字符集的 UTF-8 编码,每个字符使用一到三个字节。
  • utf8: utf8mb3 的别名。

在 8.0 之后 utf8mb3 字符集已被弃用,可能在将来的 MySQL 版本中将被删除。请改用 utf8mb4。尽管 utf8 当前是 utf8mb3 的别名,但在某些时候 utf8 有望成为对 utf8mb4 的引用。为避免对 utf8 的含义含糊不清,请考虑为字符集引用而不是 utf8 显式指定 utf8mb4。

Table Unicode 字符集的一般特征

字符集 支持的字符 单个字符需要的存储空间
utf8mb3, utf8 BMP only 1, 2, or 3 bytes
ucs2 BMP only 2 bytes
utf8mb4 BMP and supplementary 1, 2, 3, or 4 bytes
utf16 BMP and supplementary 2 or 4 bytes
utf16le BMP and supplementary 2 or 4 bytes
utf32 BMP and supplementary 4 bytes

校对规则命名约定

MySQL 校对规则名称遵循以下约定:

  • 校对规则名称以与其关联的字符集的名称开头,通常后跟一个或多个后缀,以表示其他校对特征。例如,utf8mb4_general_cilatin1_swedish_ci 分别是 utf8mb4latin1 字符集的校对规则。二进制字符集具有单个排序规则,也称为 binary,没有后缀。

  • 特定于语言的校对规则包括语言环境代码或语言名称。例如,utf8mb4_tr_0900_ai_ciutf8mb4_hu_0900_ai_ci 使用土耳其语和匈牙利语规则对 utf8mb4 字符集的字符进行排序。 相对应的 utf8mb4_turkish_ciutf8mb4_hungarian_ci ,只是基于 Unicode 排序算法的较新版本。

  • 排序规则后缀指示排序规则是否区分大小写,区分重音还是假名敏感(或其某种组合)还是二进制。下表显示了用于表示这些特征的后缀。

    Table 排序规则后缀含义

    后缀 含义
    _ai Accent-insensitive (重音不敏感)
    _as Accent-sensitive (重音敏感)
    _ci Case-insensitive (大小写不敏感)
    _cs Case-sensitive (大小写敏感)
    _ks Kana-sensitive (假名敏感)
    _bin Binary
  • Unicode 字符集的排序规则名称可以包括版本号,以指示排序规则所基于的 Unicode 排序规则算法 (UCA) 的版本。在名称中没有版本号的基于 UCA 的排序规则使用版本 4.0.0 UCA 作为其配重键。例如:

  • 对于 Unicode 字符集,xxx_general_mysql500_ci 排序规则保留原始 xxx_general_ci 排序规则在 5.1.24 之前的顺序,并允许对在 MySQL 5.1.24 之前创建的表进行升级 (Bug #27877)。