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

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

Note

该讨论主要集中在utf8mb3utf8mb4之间的转换,但是类似的原理适用于ucs2字符集和诸如utf16utf32之类的字符集之间的转换。

utf8mb3utf8mb4字符集的区别如下:

Note

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

utf8mb3转换为utf8mb4的一个优点是,这使应用程序可以使用补充字符。一种折衷是这可能增加数据存储空间需求。

就 table 内容而言,从utf8mb3转换为utf8mb4不会出现问题:

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

因此,要将 table 从utf8mb3转换为utf8mb4,可能需要更改某些列或索引定义。

可以使用ALTER TABLE将 table 从utf8mb3转换为utf8mb4。假设一个 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转换为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时,要注意的是,列或索引键的最大长度以* bytes *不变。因此,就字符而言,它更小,因为一个字符的最大长度是四个字节而不是三个字节。对于CHARVARCHARTEXT数据类型,在转换 MySQLtable 时请注意以下问题:

如果满足上述条件,则必须减少定义的列或索引的长度,或者 continue 使用utf8mb3而不是utf8mb4

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

同样,如果要将VARCHAR较长的列从utf8mb3转换为utf8mb4,则可能需要将其更改为较长的TEXT类型之一。

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

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

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

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

Note

对于使用COMPRESSEDDYNAMIC行格式的InnoDBtable,您可以启用innodb_large_prefix选项以允许索引键前缀长于 767 字节(最多 3072 字节)。创建此类 table 还需要选项值innodb_file_format=barracudainnodb_file_per_table=true。)在这种情况下,启用innodb_large_prefix选项可使您分别为utf8mb3utf8mb4列索引最多 1024 个或 768 个字符。有关相关信息,请参见第 14.23 节“ InnoDB 限制”

仅当列或索引很长时,才有可能需要进行上述更改。否则,您应该能够使用ALTER TABLE如前所述将 table 从utf8mb3转换为utf8mb4而不出现问题。

以下各项总结了其他潜在的不兼容性:

另外,请记住以下一般原则:如果 table 在主服务器和从服务器上具有不同的定义,则可能导致意外的结果。例如,最大索引键长度的差异使得在主服务器上使用utf8mb3并在从服务器上使用utf8mb4很有风险。

如果您已转换为utf8mb4utf16utf16leutf32,然后决定转换回utf8mb3ucs2(例如,降级到旧版本的 MySQL),则适用以下注意事项:

首页