浅谈MySQL中utf8和utf8mb4的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈MySQL中utf8和utf8mb4的区别相关的知识,希望对你有一定的参考价值。

一、区别

1、MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。

2、好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。

二、内容描述

1、那上面说了既然utf8能够存下大部分中文汉字,那为什么还要使用utf8mb4呢? 原来mysql支持的 utf8 编码最大字符长度为 3 字节,如果遇到 4 字节的宽字符就会插入异常了。

2、三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xffff,也就是 Unicode 中的基本多文种平面(BMP)。

3、也就是说,任何不在基本多文本平面的 Unicode字符,都无法使用 Mysql 的 utf8 字符集存储。

4、包括 Emoji 表情(Emoji 是一种特殊的 Unicode 编码,常见于 ios 和 android 手机上),和很多不常用的汉字,以及任何新增的 Unicode 字符等等。

三、问题根源

1、最初的 UTF-8 格式使用一至六个字节,最大能编码 31 位字符。最新的 UTF-8 规范只使用一到四个字节,最大能编码21位,正好能够表示所有的 17个 Unicode 平面。

2、utf8 是 Mysql 中的一种字符集,只支持最长三个字节的 UTF-8字符,也就是 Unicode 中的基本多文本平面。

3、Mysql 中的 utf8 为什么只支持持最长三个字节的 UTF-8字符呢?可能是因为 Mysql 刚开始开发那会,Unicode 还没有辅助平面这一说呢。

4、那时候,Unicode 委员会还做着 “65535 个字符足够全世界用了”的美梦。Mysql 中的字符串长度算的是字符数而非字节数,对于 CHAR 数据类型来说,需要为字符串保留足够的长。

5、当使用 utf8 字符集时,需要保留的长度就是 utf8 最长字符长度乘以字符串长度,所以这里理所当然的限制了 utf8 最大长度为 3,比如 CHAR(100) Mysql 会保留 300字节长度。

6、至于后续的版本为什么不对 4 字节长度的 UTF-8 字符提供支持,我想一个是为了向后兼容性的考虑,还有就是基本多文种平面之外的字符确实很少用到。

7、要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以后的才支持(查看版本: select version();)。

8、为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8. 对于 CHAR 类型数据,utf8mb4 会多消耗一些空间,根据 Mysql 官方建议,使用 VARCHAR 替代 CHAR。

参考技术A 一、什么是UTF8MB4

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

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

二、为什么会有UTF8MB4

既然utf8应付日常使用完全没有问题,那为什么还要使用utf8mb4呢? 低版本的MySQL支持的utf8编码,最大字符长度为 3
字节,如果遇到 4 字节的字符就会出现错误了。三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xFFFF,也就是 Unicode
中的基本多文平面(BMP)。也就是说,任何不在基本多文平面的 Unicode字符,都无法使用MySQL原有的 utf8
字符集存储。这些不在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 存储会多消耗一些空间。
参考技术B 今天升级phpmyadmin看到默认字符集是 utf8mb4

浅谈Mysql中where和having的区别

一、误区:

不要错误的认为having和group by 必须配合使用.


二、where和having用法解析:


1、 where和having都可以使用的场景:


 select goods_price,goods_name from goods where goods_price > 100


 select goods_price,goods_name from goods having goods_price > 100


解释:上面的having可以用的前提是我已经筛选出了goods_price字段,在这种情况下和where的效果是等效的。

但是如果没有select goods_price 就会报错!!因为having是从前筛选的字段再筛选,而where是从数据表中的字段直接进行的筛选的。

因此可以看到where 是针对数据库文件的发挥作用,而having是针对结果集发挥作用。

其实第二个sql语句等价于如下语句更好理解:

 select goods_price,goods_name from goods where 1  having goods_price > 100


2. 只可以用where,不可以用having的情况:


    select goods_name,goods_number from goods where goods_price > 100


    select goods_name,goods_number from goods having goods_price > 100


解释:第二个sql语句报错,这是因为前面并没有筛选goods_price 造成的,更能看出having是针对结果集发挥作用。


3. 只可以用having,不可以用where情况:

查询每种category_id商品的价格平均值,获取平均价格大于1000元的商品信息。


 select category_id , avg(goods_price) as ag from goods group by category_id having ag > 1000


 select category_id , avg(goods_price) as ag from goods where ag>1000 group by category_id 


解释:第二个sql语句报错,这是因为from goods 这张数据表里面没有ag这个字段。


三、综述:


where 后面要跟的是数据表里的字段,where针对数据库文件的发挥作用。


而having只是根据前面查询出来的结果集再次进行查询,因此having是针对结果集发挥作用。



以上是关于浅谈MySQL中utf8和utf8mb4的区别的主要内容,如果未能解决你的问题,请参考以下文章

全面了解mysql中utf8和utf8mb4的区别

全面了解mysql中utf8和utf8mb4的区别

mysql中utf8和utf8mb4区别

mysql中utf8和utf8mb4区别

MySQL utf8 和 utf8mb4 的区别

utf8mb4和utf8有啥区别