当你存储 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