Incorrect string value: ‘\xF0\x9F\x98\x83 <…’ for column ‘summary’ at row 1

2018年9月4日 作者 张舫

今天发现一个 bug:我尝试着将一个 UTf-8 编码的字符串存储到 MariaDB 的 UTF-8 编码中,然后 Rails 报了一个奇怪的错误:

这是一个 UTF-8 的客户端服务端,在一个 UTF-8 编码的数据库里面。这个字符串 「?< …」也是合法的。

但是这里却有点问题: MySQL的 utf8 不是 UTF-8

这个 「utf8」编码只支持每个字符占三个字节。真正的 UTF-8 编码是-每个人都使用,包括你自己-每个字符需要四个字节。

 

MySQL 的开发人员并没有修复这个 bug,但是他们在 2010 年发布了一个解决方案:一种叫做「utf8mb4」的新编码。

当然,他们并没有对外宣传这件事 (大概是因为这个 bug 太尴尬了),现在网上仍然有很多教程让我们使用「utf8」编码,但都是错的。

简而言之:

  • MySQL 的「utf8mb4」才是真正意义上的「UTF-8」。
  • MySQL 的「utf8」指的是「一种专有的编码」,这种编码有很多 Unicode 字符不能编码。

我在此做一个明确的声明:所有还在使用「utf8」编码的 MySQL 和 MariaDB 的用户实际上应当使用「utf8mb4」编码。而不应该继续使用「utf8」。

总而言之永远不要使用utf-8,要使用utf8mb4