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> 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这些排序方式。
character_set_client 客户端使用的字符集,相当于网页中的字符集设置character_set_connection 连接数据库的字符集设置类型,如果代码中没有指明连接数据库使用的字符集类型就按照服务器端默认的字符设置character_set_database 数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将使用服务器安装时指定的字符集设置character_set_filesystem 文件系统格式character_set_results 数据库给客户端返回时使用的字符集设定,如果没有指明,使用服务器默认的字符集character_set_server 服务器安装时指定的默认字符集设定character_set_system 数据库系统使用的字符集设定collation_connection 连接字符集的校对规则collation_database 默认数据库使用的校对规则。当默认数据库改变时服务器则设置该变量。如果没有默认数据库,变量的值同collation_servercollation_server 服务器的默认校对规则如果你的数据库还不是5.5.3+版本,请先升级你的MySQL。当然升级前备份一下你的数据库啦,以防万一。
# 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 啦!!!