由 emoji 引起的 MySQL 字符集设置一解

当你存储 emoji 的时候,如果你的字符集是 utf8 的话,数据将会出错。MySQL 为了解决这个问题,开始支持 utf8mb4,并且 utf8mb4 也完全兼容 utf8,所以在日后进行相关安装或者设定时完全可以设置字符集为 utf8mb4 了。

编译安装指定、查看、配置

编译时指定参数

-DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci

在编译时指定了 -DDEFAULT_CHARSET-DDEFAULT_COLLATION 的情况下,数据库字符集的设置情况

mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR   Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8               |
| character_set_connection | utf8               |
| character_set_database   | utf8mb4            |
| character_set_filesystem | binary             |
| character_set_results    | utf8               |
| character_set_server     | utf8mb4            |
| character_set_system     | utf8               |
| collation_connection     | utf8mb4_unicode_ci |
| collation_database       | utf8mb4_unicode_ci |
| collation_server         | utf8mb4_unicode_ci |
+--------------------------+--------------------+

我们看到还有几个变量值是 utf8,此时需要设置 my.cnf

[client]
default-character-set = 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 |
+--------------------------+--------------------+

字符集相关变量

变量注解
character_set_client客户端来源数据使用的字符集
character_set_connection连接层字符集
character_set_database当前选中数据库的默认字符集
character_set_results查询结果字符集
character_set_server默认的内部操作字符集
character_set_system系统元数据(字段名等)字符集
以 collation_ 开头的描述字符序

只让表的某个字段正常存储 emoji

users 表结构

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(120) NOT NULL,
  `email` varchar(120) NOT NULL,
  `password` varchar(60) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

在不全量修改数据库字符集设置和 my.cnf 配置文件情况下,让 name 字段可以存储 emoji 的三板斧。

  • 修改 users
ALTER TABLE `users` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  • 修改 users.name 字段
ALTER TABLE `users` CHANGE `name` `name` VARCHAR(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
  • 链接 MySQL 的服务语言,charset 要设置为 utf8mb4

全量修改数据库的三板斧

  • 修改现有的数据库
  • 修改 my.cnf,变量设置参考上面的「字符集相关变量」
  • 服务端语言建立 MySQL 链接时的设定

general_ci 和 unicode_ci 的选择

  • unicode_ci 的精确度高于 general_ci
  • unicode_ci 的速度慢于 general_ci

个人比较倾向建议使用 unicode_ci

在 stackoverflow 上关于此选择的问答 What’s the difference between utf8_general_ci and utf8_unicode_ci

其它相关资料

让 MySQL 支持 emoji 存储

深入Mysql字符集设置

    原文作者:MySql
    原文地址: https://juejin.im/entry/59b62ba86fb9a00a600f43af
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞