Emoji,这些能够表达情感的小卡通图像已经成为现代交流中不可或缺的一部分,以至于emoji这一单词已经在2015年被正式收入韦氏词典和牛津词典。说到emoji的诞生,这里还有一个很有趣的小故事:
1999年前后,日本一个名叫栗田穰崇的年轻人,和许多直男一样, 给女友发的短信经常会被误解。比如,“知道了”被解读成“生气了”、“不耐烦了”,随后引发冷战。 于是少年栗田想:“如果能在文字里插入一些表情符号来表达感情,大家应该会需要吧!”
原始的Emoji就这么诞生了
emoji 越来越流行,一个emoji 表情,有时胜过千言万语。尤其在移动端,很多用户喜欢把emoji 表情做为自己用户名称的一部分,例如微信中,就有很多朋友的用户名是这样的,如下:
这确实很好看,但这却给我们的应用程序带来了一定的问题。目前我们就碰到了一个因为用户名称中带有emoji 表情,导致数据无法存储的情况。
事情是这样的,我们的系统使用的数据库是MySQL,版本是5.5.31,最近我们发现我们的程序有不少报错,报错显示是有一些用户的数据无法保存,通过对报错日志分析,最终定位到是因为用户名中带有emoji 表情,导致数据存储失败。为什么会会数据会保存不了emoji表情呢?这里就牵涉到一个emoji的编码问题。
Emoji字符是Unicode字符集中一部分.
常见的Emoji表情符号在Unicode字符集中的范围和具体的字节映射关系, 可以在Emoji Unicode Tables中查看到.
有意思的是, 该表中还给出了同一个Emoji表情在不同系统或应用中的字体(是字体没错, Emoji的样式可通过字体文件改变)。
关于Emoji的最权威资料, 可以在Unicode® Emoji Charts上查阅到.
我们的MySQL是使用的utf8编码,但是因为UTF-8编码有可能是两个、三个、四个字节,其中Emoji表情是4个字节,而Mysql的utf8编码最多3个字节,所以导致了数据插不进去。所以为了让MySQL支持emoji表情的存储,必须要使用utf8mb4 编码。
utf8mb4作为utf8的super set,完全向下兼容,所以不用担心字符的兼容性问题。切换中需要顾虑的主要影响是mysql需要重新启动。
在升级前需要确定几件事情:
1、MySQL的版本。MySQL的版本必须为5.5.3以上的版本,如果不是需要先升级MySQL,因为之前的版本不支持utf8mb4
2、如果你用的是java服务器,升级或确保你的mysql connector版本高于5.1.13,否则仍然无法使用utf8mb4 。其它语言的暂不清楚。
mysql 修改的操作步骤需要修改以下几个地方:
1、修改mysql配置文件my.cnf
my.cnf一般在/etc/mysql/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
init_connect=\'SET NAMES utf8mb4\'
2、修改database、table字符集。参考以下语句:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3、重启mysql
4、检查字符集
character_set_system 的值是utf8没有关系,而且这个值不能改为utf8mb4,否则mysql 会启动不了。
好了,到此,数据就可以支持存储emoji 表情数据了。
总结:
1、由于目前移动互联网发展迅猛,并且emoji 越来越流行,所以为了避免在业务使用中升级MySQL字符集,最好是在部署MySQL的时候,就默认设置MySQL 支持 utf8mb4,因为utf8mb4是utf8的超集,是向下兼容,所以也不会影响utf8字符集的使用。
2、程序开发的时候,建库建表语句最好也指定库表的字符为 utf8mb4。
3、如果是已经在线的业务,而又不能重启MySQL的情况下,也可以通过应用层面转换emoji等特殊字符,以达到原数据兼容,在获取的时候,可以加一个标签注明,是否使用了emoji,这样取数据时,就再做转换就可。