记一个Emoji造成的数据库插入异常


前提

这次仍然是在我的日报系统上遇到的异常崩溃,关于日报系统的简要说明请参阅《记一次重构》.


异常信息

Incorrect string value: ‘\xF0\x9F\x8C\xB8’ for column ‘Content’ at row 49
就是说在第49行的Content这一列插入了不正确的字符串值\xF0\x9F\x8C\xB8


问题所在

这个问题倒是很好查,看来很多人都遇到过。简而言之,问题在于向数据库中插入了emoji表情。

然而问题并不是下面这种图片格式的Emoji造成的:
Emoji
因为我在解析HTML时会过滤掉<img>标签。

又经过一番搜索和验证,我发现了如下图的这种东西:
文本Emoji
表面上看,只是和上面的Emoji风格不同,实际上另有玄机!!!


真相——文本格式的Emoji

我从网站上复制了这些Emoji的一部分放到文本文档里,想看看这些东西是不是图片(图片是不能复制进文本文档的),结果看到了惊掉下巴的东西:
文本格式的Emoji
没错,这些是上述那些看似彩色图片的Emoji的真身,文本格式。


原因

那么,既然这种东西也算是一个一个的字符,为什么会出现数据库插入异常呢?
原因在于:

普通的字符串或者表情都是占位3个字节,所以utf8足够用了,但是移动端的表情符号占位是4个字节,普通的utf8就不够用了,为了应对无线互联网的机遇和挑战、避免 emoji 表情符号带来的问题、涉及无线相关的 MySQL 数据库建议都提前采用utf8mb4字符集,这必须要作为移动互联网行业的一个技术选型的要点。[1]

总之,这种字符存在于扩展之后的每个字符占4个字节的utf8mb4字符集中,转换为每个字符为3个字节的utf8就出错了。

关于utf8mb4,请移步《浅谈MySQL中utf8和utf8mb4的区别》


解决方案

根据查到的解决方案,亲测有效但是描述上有错误,我再赘述一下。

第一步——修改MySQL配置

①打开mysql的配置文件,windows下的为my.ini(linux下的为my.cnf);
②找到[client],在下面添加一行
default-character-set = utf8mb4
③找到[mysqld],在下面添加两行
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
④找到[mysql],在下面添加一行
default-character-set = utf8mb4
特别要注意的是,小心不要把这些写在以#开头的注释里。

第二步——修改字段的字符集

在数据库中,修改相应字段(我这里是text类型的Content字段)的字符集为utf8mb4,排序规则为utf8mb4_general_ci
修改字符集

第三步——修改代码中数据库连接字符串

去掉数据库连接字符串中的?characterEncoding=utf-8

因为怕出现汉字乱码的问题,我就没有做这一步试了一下,亲测是可以的。因此这一步不像网上说的必须要做,视情况而定。


后记

后来查明,是一位同学的日报中出现了这个:
导致崩溃的元凶
我问他的时候,他自己都没有意识到发了这个东西过来。可能是误触了输入法提供的这个吧。


  1. 摘自《【Mysql】存储emoji表情报错(Incorrect string value: ‘\xF0\x9F\x98\x82\xF0\x9F…’)的解决方案》 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IMplementist

你的鼓励,是我继续写文章的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值