# 10.9.8 3 字节和 4 字节 Unicode 字符集之间的转换
本节介绍了在utf8mb3
和utf8mb4
字符集。
笔记
这个讨论主要集中在之间的转换utf8mb3
和utf8mb4
, 但类似的原则适用于在ucs2
字符集和字符集如utf16
要么utf32
.
这utf8mb3
和utf8mb4
字符集的区别如下:
utf8mb3
仅支持基本多语言平面 (BMP) 中的字符。utf8mb4
还支持位于 BMP 之外的补充字符。utf8mb3
每个字符最多使用三个字节。utf8mb4
每个字符最多使用四个字节。
笔记
本次讨论是指utf8mb3
和utf8mb4
要明确引用 3 字节和 4 字节 UTF-8 字符集数据的字符集名称。例外是在表定义中,utf8
使用,因为 MySQL 转换实例utf8mb3
在此类定义中指定utf8
,这是一个别名utf8mb3
.
转换的优势之一utf8mb3
到utf8mb4
是这使应用程序能够使用补充字符。一种权衡是这可能会增加数据存储空间需求。
在表格内容方面,从utf8mb3
到utf8mb4
没有问题:
对于 BMP 字符,
utf8mb4
和utf8mb3
具有相同的存储特性:相同的代码值、相同的编码、相同的长度。对于一个补充字符,
utf8mb4
需要四个字节来存储它,而utf8mb3
根本无法存储角色。转换时utf8mb3
列到utf8mb4
,您不必担心转换补充字符,因为没有。在表结构方面,这些是主要的潜在不兼容性:
对于所有字符数据类型 (
字符
,VARCHAR
, 和文本
types),可以索引的最大字符数更少utf8mb4
列比utf8mb3
列。因此,要将表从
utf8mb3
到utf8mb4
,可能需要更改某些列或索引定义。表格可以从
utf8mb3
到utf8mb4
通过使用更改表
.假设一个表有这个定义:
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
是列或索引键的最大长度在以下方面没有变化字节.因此,它在以下方面更小人物因为一个字符的最大长度是四个字节而不是三个。为了字符
,VARCHAR
, 和文本
数据类型,在转换 MySQL 表时注意这些问题:
检查所有定义
utf8mb3
列并确保它们不超过存储引擎的最大长度。检查所有索引
utf8mb3
列并确保它们不超过存储引擎的最大长度。有时,由于存储引擎的增强,最大值可能会发生变化。如果上述条件适用,您必须减少列或索引的定义长度,或者继续使用
utf8mb3
而不是utf8mb4
.以下是一些可能需要进行结构更改的示例:
一种
小文本
列最多可以容纳 255 个字节,因此它最多可以容纳 85 个 3 字节或 63 个 4 字节字符。假设你有一个小文本
使用的列utf8mb3
但必须能够包含超过 63 个字符。您无法将其转换为utf8mb4
除非您还将数据类型更改为更长的类型,例如文本
.InnoDB
对于使用的表,最大索引长度为 767 字节[紧凑](glossary.html#glos_compact_row_format)
要么[冗余](glossary.html#glos_redundant_row_format)
行格式,所以对于utf8mb3
要么utf8mb4
列,您最多可以分别索引 255 或 191 个字符。如果您目前有utf8mb3
索引长度超过 191 个字符的列,您必须索引较少数量的字符。在一个
InnoDB
使用的表[紧凑](glossary.html#glos_compact_row_format)
要么[冗余](glossary.html#glos_redundant_row_format)
行格式,这些列和索引定义是合法的:col1 VARCHAR(500) CHARACTER SET utf8, INDEX (col1(255))
使用
utf8mb4
相反,索引必须更小:col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
笔记
为了
InnoDB
使用的表[压缩](glossary.html#glos_compressed_row_format)
要么[动态](glossary.html#glos_dynamic_row_format)
行格式,索引键前缀允许超过 767 个字节(最多 3072 个字节)。使用这些行格式创建的表允许您为最多 1024 或 768 个字符编制索引utf8mb3
要么utf8mb4
列,分别。有关相关信息,请参阅第 15.22 节,“InnoDB 限制”, 和动态行格式.只有当您有很长的列或索引时,才最可能需要上述类型的更改。否则,您应该能够将您的表格从
utf8mb3
到utf8mb4
没有问题,使用更改表
如前所述。以下项目总结了其他潜在的不兼容性:
设置名称'utf8mb4'
导致使用 4 字节字符集作为连接字符集。只要服务器没有发送 4 字节字符,就应该没有问题。否则,期望每个字符最多接收三个字节的应用程序可能会出现问题。相反,希望发送 4 字节字符的应用程序必须确保服务器能够理解它们。对于复制,如果要在源上使用支持补充字符的字符集,则所有副本也必须理解它们。
此外,请记住一般原则,如果表在源和副本上具有不同的定义,这可能会导致意外结果。例如,最大索引键长度的差异使得使用它有风险
utf8mb3
在源和utf8mb4
复制品上。如果您已转换为
utf8mb4
,utf16
,utf16le
, 要么utf32
,然后决定转换回utf8mb3
要么ucs2
(例如,要降级到旧版本的 MySQL),这些注意事项适用:utf8mb3
和ucs2
数据应该没有问题。服务器必须足够新以识别引用您要转换的字符集的定义。
对于引用的对象定义
utf8mb4
字符集,你可以用mysql转储在降级之前,编辑转储文件以更改utf8mb4
到utf8
, 并在旧服务器中重新加载文件,只要数据中没有 4 字节字符。较旧的服务器看到utf8
在转储文件对象定义中创建使用(3 字节)的新对象utf8
字符集。