TearSnow Fan


浅谈MySQL中utf8和utf8mb4的区别

一、什么是UTF8MB4?

我们在使用PhpMyAdmin管理面板时,可以在首页看到名为“Server connection collation”(服务器连接排序规则)的选项,用来选择所使用的字符集。对于我们常用的UTF8,却有utf8和utf8mb4两种,这是为什么呢?

事实上,MySQL支持很多Unicode字符集,详见Unicode Collation Algorithm (UCA)

我们可以看到,“utf8”只是“utf8mb3”的一个别名,可以支持1-3字节表示的unicode字符。

而MySQL在5.5.3版本之后增加了一个utf8mb4的编码,mb4就是most bytes 4的意思,用来兼容四字节的unicode。其实,utf8mb4是utf8的超集,理论上原来使用“utf8”,然后将字符集修改为“utf8mb4”,也并不会对已有的utf8编码读取产生任何问题。当然,为了节省空间,一般情况下使用"utf8"也就够了。

至于collation名称"utf8mb4_unicode_ci"中的"ci",则是"case insensitive"的意思。而UCA还有不同的版本,不带版本名称的一般用的是UCA 4.0.0 weight keys;而"utf8mb4_unicode_520_ci"则基于UCA 5.2.0 weight keys,需要MySQL 5.6以上版本的支持。

迁移服务器备份和恢复数据库时,经常遇到MySQL版本不同(一般是高MySQL版本向低MySQL版本迁移)造成数据库恢复错误。这时最好的解决方法当然是升级MySQL版本。

如果实在自行升级MySQL(例如使用虚拟主机),其实一般我们也较少使用到UCA 5.2.0和UCA 4.0.0有差别的编码,甚至较少使用四字节的unicode编码。所以也可以使用Notepad++等文本编辑器打开备份的“xxx.sql”,将collation名称中的“utf8mb4_unicode_520”改为“utf8mb4_unicode”,甚至将“utf8mb4”改为“utf8”来解决。

二、为什么会有UTF8MB4?

既然utf8应付日常使用完全没有问题,那为什么还要使用utf8mb4呢? 低版本的MySQL支持的utf8(utf8mb3)编码,最大字符长度为 3 字节,如果遇到 4 字节的字符就会出现错误了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xFFFF,也就是 Unicode 中的基本多文平面(BMP)。也就是说,任何不在基本多文平面的 Unicode字符,都无法使用MySQL原有的 utf8(utf8mb4)字符集存储。这些不在BMP中的字符包括哪些呢?最常见的就是Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和一些不常用的汉字,以及任何新增的 Unicode 字符等等。

三、扩展阅读:UTF-8编码

理论上将, UTF-8 格式使用一至六个字节,最大能编码 31 位字符。最新的 UTF-8 规范只使用一到四个字节,最大能编码21位,正好能够表示所有的 17个 Unicode 平面。关于UTF编码,请阅读《常见编码总结》一文。

而utf8 则是 Mysql 早期版本中支持的一种字符集,只支持最长三个字节的 UTF-8字符,也就是 Unicode 中的基本多文本平面。这可能是因为在MySQL发布初期,基本多文种平面之外的字符确实很少用到。而在MySQL5.5.3版本后,要在 Mysql 中保存 4 字节长度的 UTF-8 字符,就可以使用 utf8mb4 字符集了。例如可以用utf8mb4字符编码直接存储emoj表情,而不是存表情的替换字符。

为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8,事实上,最新版的phpmyadmin默认字符集就是utf8mb4。诚然,对于 CHAR 类型数据,使用utf8mb4 存储会多消耗一些空间。

参考资料

[1] 清官谈mysql中utf8和utf8mb4区别

[2] 常见编码总结:Unicode、UTF、ISO 8859-1等 | 小谢的小站

本文固定链接: https://blog.xieyc.com/utf8-and-utf8mb4/ | 小谢的小站

该日志由 xieyc 于2015年11月25日发表在 站长, 编程 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 浅谈MySQL中utf8和utf8mb4的区别 | 小谢的小站
关键字: , , ,

浅谈MySQL中utf8和utf8mb4的区别:等您坐沙发呢!

发表评论


快捷键:Ctrl+Enter
//added by myself XIEYC