您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

utf8mb4 和 utf8深度对比分析

时间:2023-05-10 16:49:56  来源:  作者:T锅侠

utf8mb4 和 utf8 是 MySQL 中两种常用的字符集,它们都可以用来存储 Unicode 字符,但是有一些区别和联系。本文将从以下几个方面对比 utf8mb4 和 utf8:

编码范围和存储空间

utf8 是 MySQL 中最早支持的 Unicode 字符集,它使用 1 到 3 个字节来编码每个字符,最大能表示的 Unicode 码点是 U+FFFF,也就是 Unicode 的基本多文种平面(BMP)。这意味着 utf8 不能存储一些超出 BMP 的字符,例如 Emoji 表情、部分罕用汉字、新增的 Unicode 字符等。这些字符需要 4 个字节来编码,所以 utf8 会在遇到这些字符时报错或者出现乱码。

utf8mb4 是 MySQL 在 5.5.3 版本之后增加的一个新的字符集,它是 utf8 的超集,也就是说 utf8 可以表示的字符 utf8mb4 都可以表示,而且 utf8mb4 还可以表示一些 utf8 不能表示的字符。utf8mb4 使用 1 到 4 个字节来编码每个字符,最大能表示的 Unicode 码点是 U+10FFFF,也就是 Unicode 的所有 17 个平面。这意味着 utf8mb4 可以存储任何合法的 Unicode 字符,包括 Emoji 表情、部分罕用汉字、新增的 Unicode 字符等。

由于 utf8mb4 可以使用 4 个字节来编码字符,所以它占用的存储空间会比 utf8 略大一些。例如,一个 CHAR(10) 类型的字段,如果使用 utf8 字符集,那么它需要保留 10 * 3 = 30 个字节的空间;如果使用 utf8mb4 字符集,那么它需要保留 10 * 4 = 40 个字节的空间。对于 VARCHAR 类型的字段,如果使用 utf8 字符集,那么它需要额外使用一个字节来记录字符串的长度;如果使用 utf8mb4 字符集,那么它需要额外使用两个字节来记录字符串的长度。

排序规则和性能

排序规则(collation)是指在比较和排序字符串时所遵循的规则。不同的字符集可以有不同的排序规则,甚至同一个字符集也可以有多种排序规则。MySQL 中常见的排序规则有以下几种:

  • _bin:按照二进制方式比较字符串,区分大小写和重音符号。
  • _general_ci:按照一般方式比较字符串,不区分大小写和重音符号。
  • _unicode_ci:按照 Unicode 标准方式比较字符串,不区分大小写和重音符号。
  • _ci:按照特定语言或地区方式比较字符串,不区分大小写和重音符号。

utf8 和 utf8mb4 都有以上几种排序规则,但是有一些细微的差别。例如,在 utf8_general_ci 排序规则下,'a' 等于 'A',而在 utf8mb4_general_ci 排序规则下,'a' 小于 'A'。这是因为 utf8_general_ci 排序规则只考虑了 BMP的字符,而 utf8mb4_general_ci 排序规则考虑了所有的 Unicode 字符。因此,在 utf8mb4_general_ci 排序规则下,'a' 的 Unicode 码点是 U+0061,而 'A' 的 Unicode 码点是 U+0041,所以 'a' 小于 'A'。

排序规则的不同会影响字符串的比较和排序的结果,进而影响索引的效率和查询的性能。一般来说,_bin 排序规则的性能最高,因为它只需要按照二进制方式比较字符串,不需要考虑字符的大小写和重音符号等因素。

_general_ci 排序规则的性能次之,因为它只需要按照一般方式比较字符串,不需要考虑字符的语言或地区等因素。*_unicode_ci 和 *_ci 排序规则的性能最低,因为它们需要按照 Unicode 标准或特定语言或地区的方式比较字符串,需要考虑字符的大小写和重音符号等因素。

兼容性和安全性

utf8 和 utf8mb4 的兼容性和安全性也有一些区别。由于 utf8mb4 是 utf8 的超集,所以从 utf8 切换到 utf8mb4 一般不会有问题,只需要注意存储空间的增加和排序规则的变化。但是从 utf8mb4 切换到 utf8 就可能会有问题,因为 utf8mb4 可能包含一些 utf8 不能表示的字符,这些字符在切换后会被丢弃或者转换成问号等符号。

另外,utf8mb4 也比 utf8 更安全,因为它可以防止一些恶意的攻击。例如,有一种攻击叫做 UTF-8 编码注入攻击(UTF-8 Encoding Injection Attack),它是利用 MySQL 中 utf8 字符集对 4 字节字符的处理方式来绕过一些安全检查的。

具体来说,当 MySQL 遇到一个 4 字节的 UTF-8 字符时,它会把它拆分成两个 2 字节的字符,并且忽略第一个字符。这样就可能导致一些原本不合法或者不安全的字符串变成合法或者安全的字符串。

例如,假设有一个字符串是 "xF0x90x80xE2x80xAEabc",它实际上包含了一个 4 字节的 UTF-8 字符 U+10400 和一个右至左覆盖符号 U+202E。如果使用 utf8 字符集来存储这个字符串,那么 MySQL 会把它拆分成 "xC0x80xE2x80xAEabc",并且忽略第一个字符 "xC0x80"。这样就相当于把右至左覆盖符号 U+202E 插入到了字符串中,从而改变了字符串的显示方向。

这可能会被用来进行钓鱼或者欺骗等攻击。如果使用 utf8mb4 字符集来存储这个字符串,那么 MySQL 会保留原始的字符串,并且报错或者出现乱码。

结论

utf8mb4 和 utf8 都可以用来存储 Unicode 字符,但是 utf8mb4 支持更广泛的字符范围,能够存储 Emoji 表情、罕用汉字、新增的 Unicode 字符等。utf8mb4 比 utf8 占用的存储空间略大一些,但是在性能和安全性方面更优。因此,如果需要支持更广泛的字符范围,或者需要更高的安全性和兼容性,那么应该使用 utf8mb4 字符集。当然,在选择字符集的时候,还需要考虑具体的业务需求和实际情况,选择最合适的字符集才是最重要的。



Tags:utf8   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
utf8mb4 和 utf8深度对比分析
utf8mb4 和 utf8 是 MySQL 中两种常用的字符集,它们都可以用来存储 Unicode 字符,但是有一些区别和联系。本文将从以下几个方面对比 utf8mb4 和 utf8:编码范围和存储空间utf8...【详细内容】
2023-05-10  Search: utf8  点击:(541)  评论:(0)  加入收藏
在使用中遇到 utf-8 和 utf8,它们的不同之处
"UTF-8" 是标准写法,php 在 Windows 下边英文不区分大小写,所以也可以写成 "utf-8"。"UTF-8" 也可以把中间的"-"省略,写成 "UTF8"。一般程序都能识别,但也有例外(如下文),为了严格...【详细内容】
2021-04-19  Search: utf8  点击:(500)  评论:(0)  加入收藏
utf8字符集下的比较规则
前言:在MySQL中,比较常用的字符集是utf8和utf8mb4。这两个字符集是类似的,utf8是utf8mb3的别名,所以之后在MySQL中提到utf8就意味着使用1~3个字节来表示一个字符,如果大家有使用4...【详细内容】
2020-03-30  Search: utf8  点击:(220)  评论:(0)  加入收藏
MySQL 8.0:字符集从 utf8 转换成 utf8mb4
作者:胡呈清整理 MySQL 8.0 文档时发现一个变更:默认字符集由 latin1 变为 utf8mb4。想起以前整理过字符集转换文档,升级到 MySQL 8.0 后大概率会有字符集转换的需求,在此正好分...【详细内容】
2019-12-27  Search: utf8  点击:(389)  评论:(0)  加入收藏
mysql库不能修改为utf8mb4编码,但又想存emoji表情怎么办?
前言Emoji 在我们生活中真的是越来越常见了,几乎每次发消息的时候不带个 Emoji,总觉得少了点什么,似乎干巴巴的文字已经无法承载我们丰富的感情了。对于我们开发者来说,如何将 E...【详细内容】
2019-10-28  Search: utf8  点击:(570)  评论:(0)  加入收藏
mysql数据库中utf8和utf8mb4对比总结
概述MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换...【详细内容】
2019-07-25  Search: utf8  点击:(1590)  评论:(0)  加入收藏
▌简易百科推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  爱可生开源社区    Tags:MySQL   点击:(6)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  爱可生开源社区  微信公众号  Tags:MySQL   点击:(11)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  MySQL学习  微信公众号  Tags:MySQL   点击:(10)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  字节跳动技术团队    Tags:ByteHouse   点击:(24)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10    dbaplus社群  Tags:MySQL   点击:(6)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  转转技术  微信公众号  Tags:MySQL   点击:(28)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  数据库干货铺  微信公众号  Tags:MySQL   点击:(45)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  编程技术汇    Tags:MySQL   点击:(53)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  数据库干货铺  微信公众号  Tags:MySQL   点击:(54)  评论:(0)  加入收藏
mysql索引失效的场景
MySQL中索引失效是指数据库查询时无法有效利用索引,这可能导致查询性能显著下降。以下是一些常见的MySQL索引失效的场景:1.使用非前导列进行查询: 假设有一个复合索引 (A, B)。...【详细内容】
2024-01-15  小王爱编程  今日头条  Tags:mysql索引   点击:(85)  评论:(0)  加入收藏
站内最新
站内热门
站内头条