mysql中utf8和utf8mb4的区别

mysql中 utf8 和 utf8mb4 的区别

今年上半年,优化过一批报表查询的功能,在过程中遇到了这个问题,因为两张表字段一个是 utf8 一个是 utf8mb4 ,导致查询一直无法使用索引,最后把字段全都改为 utf8mb4 就好了,当时我就只是认为这两种字符集不同,并没有继续深究下去。

今天突然在一个公众号上讲到mysql中 utf8 和 utf8mb4 的问题,于是我查了一些资料才弄懂这件事情,然后总结了一些后续使用mysql的注意事项。

问题描述

1、我遇到的情况是这样:

假设第一张表是student(学生)表,第二张表是class(班级)表。

mysql中utf8和utf8mb4的区别

studentId和classId分别是两张表的主键,现在我要查询所有学生和他们的班级信息,非常简单的一个问题,在数据量多的情况下,我突然发现这个简单的查询会变的很慢,并且把班级表的关联去掉就会瞬间出结果,我听过EXPLAIN关键字对sql进行了分析,发现的问题是class这张表关联的时候并没有走主键的索引,导致查询会扫描整张class表。

接下来我把所有可能的有可能情况都排除了,还是没有找到问题,后来无意间发现了两张表的classId虽然类型都是varchar,但两者的字符集不同,一个是 utf8 一个是 utf8mb4 ,我把两张表的类型全都改成 utf8mb4 ,就解决了这个问题。

2、我在一个公众号上看到案例:

作者在向数据库插入Emoji 表情的时候数据库报错了,也是改成 utf8mb4 之后解决了问题。

那么通过这两种情况,我们可以知道两件事情,一是 utf8 和 utf8mb4 不一样,二是 utf8 不支持Emoji 表情,那为什么会在mysql里面出现这个问题,我们到底该用哪一种字符集?

资料查询

通过查询资料,我发现这根本就是一个历史遗留问题。

utf8mb4 编码是MySQL在5.5.3之后新增的,mb4就是most bytes 4的意思,是专门拿来兼容四字节unicode,区别就是 utf8mb4 占用四个字节, utf8 占用三个字节。所以第一个问题中虽然两个类型都是varchar,但是他们的编码格式其实是不同的。

为什么会出现这种情况,我们要谈到unicode编码了,在最初的时候unicode编码是16位也就是2个字节,这样他就可以表示65536个字符,但是大家自己想想,世界上这么多语言,它们的字符数量肯定不止6万多,所以Unicode4.0定义了一组附加字符编码,附加字符编码采用2个16位来表示,也就变成了4个字节。

我们再回到mysql这个问题上, utf8 是mysql中的一种字符集,只支持最长三个字节的UTF-8字符,也就是 Unicode 中的基本多文本平面。这就解释了为什么Emoji 表情为什么存不进去,因为Emoji 表情是四个字节的。

原因很明了了,是因为在mysql最初的时候unicode都还没有辅助平面这么一说,后来需要在mysql中保存4个字节长度的字符时,就出现了 utf8mb4 ,为什么没有直接改变 utf8 呢?有人认为是为了考虑向后兼容性的问题,还有原因是4个字节的字符确实很少用到。

utf8 升级到 utf8mb4 的问题

utf8mb4 是 utf8 的超集,从旧版本的 utf8 升级到 utf8mb4 的时候,不需要担心字符转换或者丢失数据。

那么我们如何去升级呢?

SQL 语句

# 修改数据库:  
ALTER DATABASE database_name CHARACTER SET = utf8mb4  COLLATE = utf8mb4_unicode_ci;  
# 修改表:  
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;  
# 修改表字段:  
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;  

修改MySQL配置文件

新增如下参数:

default-character-set =  utf8mb4  
default-character-set =  utf8mb4     
character-set-client-handshake = FALSE  
character-set-server =  utf8mb4   
collation-server =  utf8mb4 _unicode_ci  
init_connect=‘SET NAMES  utf8mb4 ‘

检查环境变量 和测试 SQL 如下:

SHOW VARIABLES WHERE Variable_name LIKE ‘character\_set\_%‘ OR Variable_name LIKE ‘collation%‘;  

注意:MySQL版本必须为5.5.3以上版本,否则不支持字符集 utf8mb4

建议

个人觉得,虽然 utf8mb4 会多消耗空间,但是为了更好的兼容性,推荐全部使用 utf8mb4,并且使用 varchar 代替 char。

mysql中utf8和utf8mb4的区别

上一篇:mybatis-字段值为null或为''无法存储到数据库


下一篇:MYSQL——表约束条件,表之间的三种关系,表记录的增删改查操作