# Mysql的 utf8与 utf8mb4

**URL:** <https://www.isharkfly.com/t/mysql-utf8-utf8mb4/15455>\
**Category:** 数据库\
**Tags:** mariadb, mysql\
**Created:** [February 5, 2024, 4:40am UTC](https://www.isharkfly.com/t/mysql-utf8-utf8mb4/15455 "2024-02-05T04:40:43Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![honeymoose](https://www.isharkfly.com/user_avatar/www.isharkfly.com/honeymoose/32/20796_2.png) [@honeymoose](https://www.isharkfly.com/u/honeymoose)\
**Post date:** [February 5, 2024, 4:40am UTC](https://www.isharkfly.com/t/mysql-utf8-utf8mb4/15455/1 "2024-02-05T04:40:43Z")

</div>

UTF-8是使用1~4个字节，一种变长的编码格式，字符编码。mb4即 most bytes 4，使用4个字节来表示完整的UTF-8。

mysql的 utf8 编码最大字符长度为 3 字节，如果遇到 4 字节的宽字符就会插入异常了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xffff，也就是 Unicode 中的基本多文种平面(BMP)。

也就是说，任何不在基本多文本平面的 Unicode字符，都无法使用 Mysql 的 utf8 字符集存储。包括 Emoji 表情(Emoji 是一种特殊的 Unicode 编码，常见于 ios 和 android 手机上)，和很多不常用的汉字，以及任何新增的 Unicode 字符等等。

MySQL的utf8是utfmb3，只有三个字节，节省空间但不能表达全部的UTF-8。

所以目前都会使用 utf8mb4 来作为 MySQL 的字符集。

 ![2024-02-04_23-40-07](https://cdn.isharkfly.com/com-isharkfly-www/discourse-uploads/original/2X/6/62867ec8b13375f53298fdbec4b52b91eaf883e7.png)

**utf8mb4\_bin** ：将字符串每个字符用二进制数据编译存储，区分大小写，而且可以存二进制的内容。

**utf8mb4\_general\_ci** ：ci即case insensitive，不区分大小写。没有实现Unicode排序规则，在遇到某些特殊语言或者字符集，排序结果可能不一致。但是，在绝大多数情况下，这些特殊字符的顺序并不需要那么精确。

同时这个字符集还是一个遗留的 校对规则，不支持扩展，它仅能够在字符之间进行逐个比较。utf8\_general\_ci校对规则进行的比较速度很快，但是与使用 utf8mb4\_unicode\_ci的校对规则相比，比较正确性较差。

**utf8mb4\_unicode\_ci** ：是基于标准的Unicode来排序和比较，能够在各种语言之间精确排序，Unicode排序规则为了能够处理特殊字符的情况，实现了略微复杂的排序算法。

总结：general\_ci 更快，unicode\_ci 更准确。但相比现在的CPU来说，它远远不足以成为考虑性能的因素，索引涉及、SQL设计才是。

使用者更应该关心字符集与排序规则在db里需要统一。（可能产生乱码的字段不要作为主键或唯一索引。例如：以 url 来作为唯一索引，但是它记录的有可能是乱码。）

对我们具体来说，在生产环境中，我们大概率会使用 utf8mb4\_bin 这个字符集。

因为对当前的计算机系统来说，当前的处理能够已经足够强大，在如何保持数据的准确性上面会有更高的要求。
