MySQL UTF-8的坑

背景


MySQL的UTF-8并不是“真正”的UTF-8,实际只支持最大3个字节。这样会导致,当插入数据包含emoji表情时,数据库会报错。
真正的UTF-8是每个字符最多4个字节。
因此,MySQL官方在2010年发布了一个不同于UTF-8的字符集,叫utf8mb4。

编码参数


首先我们查看一下当前数据库的编码和排序规则


MySQL UTF-8的坑_第1张图片
image.png

我们关心的几个变量是

  • character_set_server:默认的内部操作字符集
  • character_set_client:客户端来源数据使用的字符集
  • character_set_connection:MySQL接受到用户查询后,按照character_set_client将其转化为
  • character_set_connection设定的字符集。
  • character_set_results:查询结果编码的字符集
  • character_set_database:当前选中数据库的默认字符集

迁移


那我们需要从utf8迁移到utf8mb4时,需要做哪些事情呢?

  1. 修改数据库、表的编码
# For each database:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# For each table:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# For each column:
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# (Don’t blindly copy-paste this! The exact statement depends on the column type, maximum length, and other properties. The above line is just an example for a `VARCHAR` column.)
  1. 需要注意utf8mb4会影响列和索引的长度,例如tinytext可以存储255字节,相当于是85个三字节或63个四字节,如果一个tinytext类型的列,从utf8转为utf8mb4,那它能存储的字节数就变少了。
    同理,索引也有这个影响,InnoDB引擎最大存储767个字节,对应utf8和utf8mb4,相当于255或191个字符。
    因此,在修改编码时,需要注意这个影响
  2. 修改mysql数据库配置:修改mysql连接编码为utf8mb4,最简单的方法可以执行 set names utf8mb4,但这只影响单次连接。一劳永逸的方法是修改mysql配置(需要注意,如果是生产环境,这个不太好处理)
[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

JDBC


如果使用MySQL Connector,需要清楚一下几点:

  1. 对于5.1.46或更早的 Connector版本,mysql服务器必须设置character_set_server=utf8mb4,否则会使用utf8
  2. 对于5.1.47或更后面的版本,指定characterEncoding=UTF-8,会默认映射为utf8mb4
  3. 不要使用查询来set names,因为驱动不会检测编码被更改,仍然会使用最开始建立连接时使用的编码

参考文档


  • https://www.cnblogs.com/JMLiu/p/8313204.html
  • https://mathiasbynens.be/notes/mysql-utf8mb4
  • https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-charsets.html

你可能感兴趣的:(MySQL UTF-8的坑)