了解 MySQL 中的 utf8 和 utf8mb4

Dec 26, 2019

UTF-8 使用一至六个 字节 为每个字符编码(尽管如此,2003年11月UTF-8被RFC 3629重新规范,只能使用原来Unicode定义的区域,U+0000到U+10FFFF,也就是说最多 四个字节 )。然而在MySQL的utf8编码的每个符号最多 三个字节 ,所以它的别名也叫 utf8mb3 ,它支持的范围只有U+000000到U+00FFFF,当我们存入一个正常UTF-8编码的字符但有超过MySQL的utf8字符编码范围的内容时就会有问题了,例如Emoji表情。

我们要清楚的知道,MySQL的utf8是不能等同于我们一般认为的UTF-8的,它不能提供完整的Unicode支持,所以是有可能导致数据丢失或安全性问题。

MySQL在5.5.3之后提供了一个新的编码方式── utf8mb4 ,它支持正常的UTF-8和完整的Unicode,甚至是星座符号,例如♈,哈哈,是不是强大了不少。因此,我们在使用MySQL时,最好使用utf8mb4这个编码方式。

查看当前MySQL字符集

mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+

10 rows in set (0.00 sec)

上面展示的参数还是很多的,它们是什么意思,相互之间又有什么关系呢?

MySQL有两个字符集概念:一个就是字符集本身(character开头的),一个是字符集校验规则(collation开头的)。字符集影响数据在传输和存储过程中的处理方式,而字符集校验则影响ORDER BY和GROUP BY这些排序方式。

如果你的数据库还不是5.5.3+版本,请先升级你的MySQL。当然升级前备份一下你的数据库啦,以防万一。

修改databases,tables和columns字符集的方法

# 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.)

还有一点要注意的是 utf8mb4 是向下兼容 utf8 的,所以也不用担心改变字符集导致数据丢失的问题。

修改连接,客户端和服务器字符集

在代码中可以通过简单的 SET NAMES utf8mb4 来完成更换。当使用 SET NAMES utf8mb4 时,其实就是执行了下面三句:

SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_connection = utf8mb4;

而服务器的字符集一般是在启动配置 /etc/my.cnf 中配置的,例如:

[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

总而言之,从现在开始,我们 尽量在MySQL中使用 utf8mb4 而不要再使用 utf8 啦!!!

参考资料