mysql 编码的的坑——utf8不是UTF-8?

1,652 阅读1分钟

这两天我碰到一个bug,在向数据库插入数据的时候提示错误: 1366 - Incorrect string value: '\xF0\x9F\x91\xA6' for column 'name' at row 1

我当时排查了一段时间,发现症状出现在我的输入上——有一个 emoji 字符。这我就很好奇了,utf8难道不能存储emoji吗?号称可以存储所有字符的 utf8 就这?

当时找到的解决方案是,将utf8改成utf8mb4就可以了(想到这个的原因是因为另一张表里面存储的字符集是utf8mb4)。

那么,为什么?


先来说说 mysql 5.7 中的 utf8 是什么?

来源:mysql 官方文档 10.9.3 The utf8 Character Set (Alias for utf8mb3) utf8 is an alias for the utf8mb3 character set. For more information, see Section 10.9.2, “The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)”.

简单翻译一下就是,utf8 是 utf8mb3 的别名,mysql中创建的 utf8 (具有3个字节)不是广义上认为的UTF-8(具有4个字节)。 而我们需要的应该是 utf8mb4。我们可以通过更改表、字段的编码,将原有的表更改为 utf8mb4 字符集,随后就可以插入 emoji 字符了。

来源:mysql 官方文档 Note The utf8mb3 character set is deprecated and will be removed in a future MySQL release. Please use utf8mb4 instead. Although utf8 is currently an alias for utf8mb3, at some point utf8 will become a reference to utf8mb4. To avoid ambiguity about the meaning of utf8, consider specifying utf8mb4 explicitly for character set references instead of utf8.

在 mysql 8 中,默认的字符集将会被更改为 utf8mb4,同时在未来的版本中可能会删除 utf8mb3 字符集,尽管目前 utf8 仍然会指向 utf8mb3,但是任然不建议显示使用,尽量使用 utf8mb4。