MySQL VS Emoji

最近做了个用户登录功能,发现个别用户的名称无法正确存储到数据库中。

开始以为是前端传错了,将前端传的数据直接存到 Redis 中,花了一天的时间终于再次发现错误数据:用户名后中,Emoji 和后面的字符串都没了。手动跑 SQL 语句,直接抛错。

原因是我这个字段使用的 utf8_unicode_ci 无法存储 Emoji。

还有这种事情,utf8 诶。原来 utf8_unicode_ci 只能存储 3 个字节的字符,无法应对 Emoji 这种需要 4 个字节的字符。

弄清楚问题,解决起来就简单了,修改字符集为 utf8mb4。不过修改的时候又碰到 1 个问题:utf8mb4_bin, utf8mb4_unicode_ci, utf8mb4_general_ci 应该选哪个?

参考 MySQL 的 官方文档, ci 后缀表示不区分大小写(case insensitive),bin 因为通过二进制比较,所以区分大小写:参考 stackoverflow 的这篇 回答 unicode 在对很多语言来说排序和比较是准确的,但是相对慢一些,general 没有实现所有的 Unicode 排序规则,有些语言会有问题,但是快一些,不过到具体实践中,中文没什么差别,速度相差无几,我觉得用 unicode 更好一些,少留坑,

还好我的表数据量不大,线上很快就转换完了,几百万数据就得半夜三更弄了。

改完数据表还没结束,代码中连接数据库时指定的字符集也得改为 utf8mb4

Laravel 5.4 已经在配置文件中,默认使用 utf8mb4,赞!

以前用 Redis 和 Mongo 时,从来没遇到这个问题,不禁想问:为什么 MySQL 不只使用 unicode 字符集?为啥弄这么多字符集?utf8 还没支持全。大概是历史过于悠久,早期的时候,unicode 还没有发展成现在这样吧。

另外 这篇 谈字符集的也很不错。

标签: none

添加新评论