Documentation Home
MySQL 8.0 参考手册  / 第 10 章字符集、排序规则、Unicode  / 10.9 Unicode 支持  /  10.9.8 在 3 字节和 4 字节 Unicode 字符集之间转换

10.9.8 在 3 字节和 4 字节 Unicode 字符集之间转换

utf8mb3本节介绍在和 utf8mb4字符集 之间转换字符数据时可能遇到的问题。

笔记

此讨论主要集中在 和 之间的转换 utf8mb3utf8mb4但类似的原则适用于 ucs2字符集与字符集(例如utf16或)之间的转换utf32

utf8mb3和字符集 的utf8mb4 区别如下:

  • utf8mb3仅支持基本多语言平面 (BMP) 中的字符。utf8mb4 另外还支持位于 BMP 之外的增补字符。

  • utf8mb3每个字符最多使用三个字节。utf8mb4每个字符最多使用四个字节。

笔记

此讨论引用utf8mb3utf8mb4字符集名称以明确引用 3 字节和 4 字节 UTF-8 字符集数据。例外是在表定义中, 因为 MySQL 将此类定义utf8中指定的实例转换为,这是 的别名 。 utf8mb3utf8utf8mb3

utf8mb3将 from 转换为to 的 一个优点utf8mb4是这使应用程序能够使用增补字符。一个权衡是这可能会增加数据存储空间需求。

就表格内容而言,从 utf8mb3到的转换utf8mb4 没有问题:

  • 对于一个BMP字符,utf8mb4具有 utf8mb3相同的存储特性:相同的码值、相同的编码、相同的长度。

  • 对于增补字符,utf8mb4 需要四个字节来存储,而 utf8mb3根本不能存储字符。将utf8mb3列转换为 时 utf8mb4,您不必担心转换增补字符,因为没有增补字符。

就表结构而言,这些是主要的潜在不兼容性:

  • 对于可变长度字符数据类型(VARCHARTEXT类型),列的最大允许字符长度小于 utf8mb4utf8mb3

  • 对于所有字符数据类型(CHARVARCHAR和 类型),列 TEXT可以索引的最大字符数少于 列。 utf8mb4utf8mb3

因此,要将表从 转换utf8mb3utf8mb4,可能需要更改某些列或索引定义。

可以使用 将表从转换utf8mb3为 。假设一个表有这样的定义: utf8mb4ALTER TABLE

CREATE TABLE t1 (
  col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) CHARACTER SET utf8;

以下语句转换t1为 use utf8mb4

ALTER TABLE t1
  DEFAULT CHARACTER SET utf8mb4,
  MODIFY col1 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  MODIFY col2 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;

utf8mb3从到 转换时utf8mb4的问题是列或索引键的最大长度以 字节为单位不变。因此,它在 字符方面更小,因为字符的最大长度是四个字节而不是三个。对于 CHARVARCHARTEXT数据类型,在转换 MySQL 表时注意这些问题:

  • 检查utf8mb3列的所有定义并确保它们不超过存储引擎的最大长度。

  • 检查utf8mb3列上的所有索引并确保它们不超过存储引擎的最大长度。有时由于存储引擎的增强,最大值可能会发生变化。

如果上述条件适用,您必须减少列或索引的定义长度,或者继续使用 utf8mb3rather than utf8mb4.

以下是一些可能需要进行结构更改的示例:

  • TINYTEXT列最多可容纳 255 个字节,因此它最多可容纳 85 个 3 字节或 63 个 4 字节字符。假设您有一个 TINYTEXT使用 utf8mb3但必须能够包含超过 63 个字符的列。您无法将其转换为, utf8mb4除非您还将数据类型更改为更长的类型,例如 TEXT.

    同样,如果要将 很长的 VARCHAR列 从 . TEXTutf8mb3utf8mb4

  • InnoDB对于使用 COMPACT or REDUNDANT 行格式的表,最大索引长度为 767 字节,因此对于utf8mb3or utf8mb4列,您最多可以分别索引 255 或 191 个字符。如果您当前的utf8mb3列的索引长度超过 191 个字符,则必须索引更少的字符。

    InnoDB使用 COMPACTREDUNDANT 行格式的表中,这些列和索引定义是合法的:

    col1 VARCHAR(500) CHARACTER SET utf8, INDEX (col1(255))

    utf8mb4改为使用,索引必须更小:

    col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
    笔记

    For InnoDB tables that use COMPRESSED or DYNAMIC row format, you can enable the innodb_large_prefix option to permit index key prefixes longer than 767 bytes (up to 3072 bytes). Creating such tables also requires the option values innodb_file_format=barracuda and innodb_file_per_table=true.) In this case, enabling the innodb_large_prefix option enables you to index a maximum of 1024 or 768 characters for utf8mb3 or utf8mb4 columns, respectively. For related information, see Section 14.23, “InnoDB Limits”.

The preceding types of changes are most likely to be required only if you have very long columns or indexes. Otherwise, you should be able to convert your tables from utf8mb3 to utf8mb4 without problems, using ALTER TABLE as described previously.

The following items summarize other potential incompatibilities:

  • SET NAMES 'utf8mb4' causes use of the 4-byte character set for connection character sets. As long as no 4-byte characters are sent from the server, there should be no problems. Otherwise, applications that expect to receive a maximum of three bytes per character may have problems. Conversely, applications that expect to send 4-byte characters must ensure that the server understands them.

  • For replication, if character sets that support supplementary characters are to be used on the source, all replicas must understand them as well.

    Also, keep in mind the general principle that if a table has different definitions on the source and replica, this can lead to unexpected results. For example, the differences in maximum index key length make it risky to use utf8mb3 on the source and utf8mb4 on the replica.

If you have converted to utf8mb4, utf16, utf16le, or utf32, and then decide to convert back to utf8mb3 or ucs2 (for example, to downgrade to an older version of MySQL), these considerations apply:

  • utf8mb3 and ucs2 data should present no problems.

  • 服务器必须足够新以识别引用您正在转换的字符集的定义。

  • 对于引用 utf8mb4字符集的对象定义,您可以在降级之前 使用mysqldumputf8mb4转储它们,编辑转储文件以将实例更改为utf8,并在旧服务器中重新加载文件,只要其中没有 4 字节字符数据。较旧的服务器 utf8在转储文件中看到对象定义并创建使用(3 字节) utf8字符集的新对象。