控件之间转换字符数据时可能遇到的问题utf8mb3
和utf8mb4
字符集。
这个讨论主要集中在utf8mb3
和utf8mb4
,但类似的原则适用于转换之间ucs2
字符集和字符集等utf16
或者utf32
。
的utf8mb3
和utf8mb4
不同的字符集如下:
utf8mb3
BMP (Basic Multilingual Plane)中仅支持字符。utf8mb4
另外还支持BMP之外的补充字符。utf8mb3
每个字符最多使用三个字节。utf8mb4
每个字符最多使用4个字节。
这个讨论是指utf8mb3
和utf8mb4
字符集名称要显式引用3字节和4字节UTF-8字符集数据。例外的是,在表定义中,use utf8
使用,因为mysql转换了实例utf8mb3
在这些定义中指定use utf8
的别名utf8mb3
。
从utf8mb3
来utf8mb4
这使得应用程序可以使用补充字符。一个权衡是,这可能会增加数据存储空间的需求。
就表内容而言,从utf8mb3
来utf8mb4
礼物没有问题:
对于BMP字符,
utf8mb4
和utf8mb3
具有相同的存储特征:相同的代码值,相同的编码,相同的长度。对于补充字符,
utf8mb4
需要四个字节来存储,然而utf8mb3
根本不能存储字符。当转换utf8mb3
列utf8mb4
,您不必担心转换补充字符,因为没有补充字符。
就表结构而言,以下是主要的潜在不兼容性:
因此,转换表从utf8mb3
来utf8mb4
,可能需要更改一些列或索引定义。
表可以从utf8mb3
来utf8mb4
通过使用ALTER 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 col2 CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,修改col2 CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL
转换时的捕获utf8mb3
来utf8mb4
是一个列或索引键的最大长度不变的条款字节。因此,它的方面较小字符因为字符的最大长度为四个字节而不是三个。为了字符
,VARCHAR
,文本
数据类型,当转换MySQL表时注意这些问题:
检查所有定义
utf8mb3
列,并确保它们不超过存储引擎的最大长度。检查所有索引
utf8mb3
列,并确保它们不超过存储引擎的最大长度。有时,由于存储引擎的增强,最大值可能会发生变化。
如果上述条件适用,则必须减少列或索引的定义长度,或者继续使用utf8mb3
而不是utf8mb4
。
以下是一些可能需要进行结构调整的例子:
一个
非常小的文本串
Column最多可以容纳255个字节,因此它最多可以容纳85个3字节或63个4字节字符。假设你有非常小的文本串
列,使用utf8mb3
但必须能够包含超过63个字符。你不能把它转换成utf8mb4
除非您还将数据类型更改为更长的类型,例如文本
。InnoDB
对于使用的表,最大索引长度为767字节紧凑的
或者冗余
行格式,所以utf8mb3
或者utf8mb4
列,可以分别索引最多255或191个字符。如果你现在有utf8mb3
索引超过191个字符的列,必须索引较少的字符。在一个
InnoDB
表使用紧凑的
或者冗余
行格式,这些列和索引定义是合法的:字符集utf8,索引(col1(255))
使用
utf8mb4
相反,索引必须更小:字符集utf8mb4,索引(col1(191))
请注意为
InnoDB
表的使用压缩
或者动态
行格式,可以启用innodb_large_prefix
选择允许索引键的前缀大于767字节(最多3072字节)。创建这样的表还需要选项值innodb_file_format =梭子岛
和innodb_file_per_table = true
)。在这种情况下,启用innodb_large_prefix
选项允许您索引最多1024或768个字符utf8mb3
或者utf8mb4
分别列。相关信息请参见第14.23节“InnoDB限制”。
只有当您有很长的列或索引时,才最有可能需要上述类型的更改。否则,您应该能够将表从utf8mb3
来utf8mb4
没有问题,使用ALTER TABLE
如前所述。
以下项目总结了其他潜在的不兼容性:
设置名称“utf8mb4”
导致将4字节字符集用于连接字符集。只要没有从服务器发送4字节的字符,就应该没有问题。否则,希望每个字符最多接收三个字节的应用程序可能会有问题。相反,希望发送4字节字符的应用程序必须确保服务器能够理解它们。对于复制,如果要在源上使用支持补充字符的字符集,那么所有副本也必须理解它们。
另外,请记住这样的一般原则:如果一个表在源和副本上有不同的定义,这可能会导致意外的结果。例如,最大索引键长度的差异使得使用它有风险
utf8mb3
关于来源和utf8mb4
在副本。
如果你已经转换为utf8mb4
,utf16
,utf16le
,或utf32
,然后决定转换回utf8mb3
或者ucs2
(例如,降级到一个旧版本的MySQL),这些注意事项适用:
utf8mb3
和ucs2
数据不会出现任何问题。服务器必须近来足以识别指定从您正在转换的字符集的定义。
引用的对象定义
utf8mb4
字符集,你可以转储它们, mysqldump在降级之前,编辑转储文件以更改实例utf8mb4
来use utf8
,并在旧服务器中重新加载文件,只要数据中没有4字节字符。旧的服务器看到use utf8
在转储文件中对象定义并创建使用(3字节)的新对象use utf8
字符集。