前两天朋友问我后台处理表情包有没有乱码的情况,我就想到之前做过这样的项目,也碰到过这钟乱码的情况,在此记录一下:
step1:修改数据库编码格式为utf8mb4
MySQL 在 5.5.3 版本之后增加了这个 utf8mb4 的编码,mb4 就是 most bytes 4 的意思,专门用来兼容四字节的 unicode。其实,utf8mb4 是 utf8 的超集,理论上原来使用 utf8,然后将字符集修改为 utf8mb4,也会不会对已有的 utf8 编码读取产生任何问题。当然,为了节省空间,一般情况下使用 utf8 也就够了。
既然utf8应付日常使用完全没有问题,那为什么还要使用utf8mb4呢?
低版本的 MySQL 支持的 utf8 编码,最大字符长度为 3 字节,如果遇到 4 字节的字符就会出现错误了。
三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xFFFF,也就是 Unicode 中的基本多文平面(BMP)。也就是说,任何不在基本多文平面的 Unicode 字符,都无法使用 MySQL 原有的 utf8 字符集存储。
这些不在 BMP 中的字符包括哪些呢?最常见的就是 Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和一些不常用的汉字,以及任何新增的 Unicode 字符等等。
要在 Mysql 中保存 4 字节长度的 UTF-8 字符,就可以使用 utf8mb4 字符集了。例如可以用 utf8mb4 字符编码直接存储 emoj 表情,而不是存表情的替换字符。
为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8,事实上,最新版的 phpmyadmin 默认字符集就是 utf8mb4。诚然,对于 CHAR 类型数据,使用 utf8mb4 存储会多消耗一些空间。根据 Mysql 官方建议,使用 VARCHAR 替代 CHAR。
另外,如果你用的是 Java 服务器,升级或确保你的 mysql connector 版本高于 5.1.13,否则仍然无法使用 utf8mb4。
step2:修改表中存储评论、回复字段的类型为blob
blob 为二进制存储。这一步是在前面修改数据库编码没有还是没有效果的情况下尝试。一般只需修改数据库编码即可。
当然,也可以客户端做一个 emojj 库,存取的时候用自定义字符进行替换。但这样应该会比较麻烦。