utf8mb3
本节介绍在和
utf8mb4
字符集
之间转换字符数据时可能遇到的问题。
此讨论主要集中在 和 之间的转换
utf8mb3
,utf8mb4
但类似的原则适用于
ucs2
字符集与字符集(例如utf16
或)之间的转换utf32
。
utf8mb3
和字符集
的utf8mb4
区别如下:
utf8mb3
仅支持基本多语言平面 (BMP) 中的字符。utf8mb4
另外还支持位于 BMP 之外的增补字符。utf8mb3
每个字符最多使用三个字节。utf8mb4
每个字符最多使用四个字节。
此讨论引用utf8mb3
和
utf8mb4
字符集名称以明确引用 3 字节和 4 字节 UTF-8 字符集数据。
utf8mb3
将 from 转换为to
的
一个优点utf8mb4
是这使应用程序能够使用增补字符。一个权衡是这可能会增加数据存储空间需求。
就表格内容而言,从
utf8mb3
到的转换utf8mb4
没有问题:
对于一个BMP字符,
utf8mb4
具有utf8mb3
相同的存储特性:相同的码值、相同的编码、相同的长度。对于增补字符,
utf8mb4
需要四个字节来存储,而utf8mb3
根本不能存储字符。将utf8mb3
列转换为 时utf8mb4
,您不必担心转换增补字符,因为没有增补字符。
就表结构而言,这些是主要的潜在不兼容性:
因此,要将表从 转换utf8mb3
为utf8mb4
,可能需要更改某些列或索引定义。
可以使用 将表从转换utf8mb3
为
。假设一个表有这样的定义:
utf8mb4
ALTER
TABLE
CREATE TABLE t1 (
col1 CHAR(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL,
col2 CHAR(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL
) CHARACTER SET utf8mb3;
以下语句转换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
的问题是列或索引键的最大长度以
字节为单位不变。因此,它在
字符方面更小,因为字符的最大长度是四个字节而不是三个。对于
CHAR
、
VARCHAR
和
TEXT
数据类型,在转换 MySQL 表时注意这些问题:
检查
utf8mb3
列的所有定义并确保它们不超过存储引擎的最大长度。检查
utf8mb3
列上的所有索引并确保它们不超过存储引擎的最大长度。有时由于存储引擎的增强,最大值可能会发生变化。
如果上述条件适用,您必须减少列或索引的定义长度,或者继续使用
utf8mb3
rather than
utf8mb4
.
以下是一些可能需要进行结构更改的示例:
一
TINYTEXT
列最多可容纳 255 个字节,因此它最多可容纳 85 个 3 字节或 63 个 4 字节字符。假设您有一个TINYTEXT
使用utf8mb3
但必须能够包含超过 63 个字符的列。您无法将其转换为,utf8mb4
除非您还将数据类型更改为更长的类型,例如TEXT
.InnoDB
对于使用COMPACT
orREDUNDANT
行格式的表,最大索引长度为 767 字节,因此对于utf8mb3
orutf8mb4
列,您最多可以分别索引 255 或 191 个字符。如果您当前的utf8mb3
列的索引长度超过 191 个字符,则必须索引更少的字符。在
InnoDB
使用COMPACT
或REDUNDANT
行格式的表中,这些列和索引定义是合法的:col1 VARCHAR(500) CHARACTER SET utf8mb3, INDEX (col1(255))
要
utf8mb4
改为使用,索引必须更小:col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
笔记对于使用 或 行格式的
InnoDB
表,允许使用 超过 767 字节(最多 3072 字节)的索引键前缀。使用这些行格式创建的表使您能够分别为或 列索引最多 1024 或 768 个字符。有关相关信息,请参阅第 15.22 节,“InnoDB 限制”和动态行格式。COMPRESSED
DYNAMIC
utf8mb3
utf8mb4
仅当您的列或索引非常长时,才最有可能需要进行上述类型的更改。否则,您应该能够毫无问题地将表从 转换
utf8mb3
为utf8mb4
,ALTER TABLE
如前所述使用。
以下项目总结了其他潜在的不兼容性:
SET NAMES 'utf8mb4'
导致使用 4 字节字符集作为连接字符集。只要服务器没有发送 4 字节的字符,应该就没有问题。否则,期望每个字符最多接收三个字节的应用程序可能会出现问题。相反,希望发送 4 字节字符的应用程序必须确保服务器能够理解它们。对于复制,如果要在源上使用支持增补字符的字符集,则所有副本也必须理解它们。
此外,请记住一般原则,如果表在源和副本上有不同的定义,这可能会导致意外结果。例如,最大索引键长度的差异使得
utf8mb3
在源和utf8mb4
副本上使用存在风险。
如果您已转换为utf8mb4
、
utf16
、utf16le
或
utf32
,然后决定转换回
utf8mb3
或ucs2
(例如,降级到旧版本的 MySQL),则适用以下注意事项:
utf8mb3
ucs2
数据应该没有问题 。服务器必须足够新以识别引用您正在转换的字符集的定义。
对于引用
utf8mb4
字符集的对象定义,您可以在降级之前 使用mysqldumputf8mb4
转储它们,编辑转储文件以将实例更改为utf8
,并在旧服务器中重新加载文件,只要其中没有 4 字节字符数据。旧服务器utf8
在转储文件中查看对象定义并创建使用(3 字节)utf8
字符集的新对象。