一个emoji引发的一条血案:mysql存储emoji表情字符时报错解决
以下是我插入一条带表情的数据到mysql后出现错误
2019-03-04 14:24:40,462 ERROR 2807 [-/139.199.27.244/-/2ms POST /api/activityAdd] nodejs.ER_TRUNCATED_WRONG_VALUE_FOR_FIELDError: ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value: '\xF0\x9F\x98\x82' for column 'content' at row 1
报错原因:
mysql的utf8编码的一个字符最多3个字节,但是一个emoji表情为4个字节,所以utf8不支持存储emoji表情。但是utf8的超集utf8mb4一个字符最多能有4字节,所以能支持emoji表情的存储
解决办法:
解决方式有2种:
1、在前端通过js对字符串进行编码然后再保存到数据库中,取出来时再对内容进行解码
2、通过修改数据库字符编码utf8mb4
第一种解决方式是使用js提供的方法escape和unescape来对内容进行编解码,但是问题也很明显,就是在每个需要显示和保存的地方我们都需要使用escape和unescape去做处理,这无疑增加了工作量。还有就是我们使用escape编码之后的内容长度特别长,在数据库表字段上需要设计很大的长度,对数据库性能影响也比较大
综合考虑排除掉这种方式,使用第二种方式去解决
解决过程:
1、linux中修改my.cnf配置文件(默认路径/etc/my.cnf)
关于my.cnf配置文件参数说明
https://baijiahao.baidu.com/s?id=1608929505838938265&wfr=spider&for=pc
修改之前先查看当前数据库字符编码
SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
character_set_client utf8mb4
character_set_connection utf8mb4
character_set_database utf8
character_set_filesystem binary
character_set_results utf8mb4
character_set_server latin1
character_set_system utf8
character_sets_dir /usr/local/mysql/share/charsets/
collation_connection utf8mb4_general_ci
collation_database utf8_bin
collation_server latin1_swedish_ci
可以看到目前我们数据库编码使用的是utf8
关于collation_connection 、collation_database 、collation_server关系
系统变量 描述
character_set_client (客户端来源数据使用的字符集)
character_set_connection (连接层字符集)
character_set_database (当前选中数据库的默认字符集)
character_set_results (查询结果字符集)
character_set_server (默认的内部操作字符集)
之后,我们在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'
然后重启mysql
service mysqld restart
将数据库和已经建好的表也转换成utf8mb4
以上方式更改编码对于已有的库和表是不产生影响的,需要我们单独进行转换。
更改数据库编码:ALTER DATABASE caitu99 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
更改表编码:ALTER TABLE TABLE_NAME CONVERT TO CHARACTER SET utf8mb4 COLLATEutf8mb4_general_ci;
如有必要,还可以更改列的编码
修改后需要再重启mysql服务
插入一条表情数据测试
INSERT INTO tb_test (id,name) VALUES (55, x'F09F9A8A');
参考阅读
https://blog.csdn.net/asahinokawa/article/details/85255732
https://www.cnblogs.com/zhangwufei/p/7017325.html
https://dba.stackexchange.com/questions/89355/unable-to-insert-utf8mb4-characters-in-mysql-5-6
https://blog.csdn.net/eagle89/article/details/82148751
https://www.cnblogs.com/chyingp/p/mysql-character-set-collation.html
文章出处:https://www.cnblogs.com/fozero
声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。