八股:MySQL 中 varchar 和 char 有什么区别?

画板

对话解析

char和 varchar的区别

大佬: 我今天遇到个新问题,Mysql建表的时候,那个char类型和varchar类型有啥区别的,不都是字符串吗?

凯歌: 这俩啊,说的确实没问题,都是存字符串的,不过确实有点区别,我给你列个表,你直观感受下。

不同点CHARVARCAHR
存储方式不同定长字符串(长度不足,空格补齐)变长字符串
占用空间不同始终占用固定长度需要多少,占用多少
性能不同长度固定,可能会浪费空间需要多少,存多少,可以节省一些空间,但是某些情况下,可能会影响性能
适用场景不同适合存储固定且短的字符串适合存储变化或较长的字符串

大佬: 哦哦,看这个表格,我大概知道啥区别了,就是一个直尺,一个是卷尺呗?能变不能变的。

凯歌: 对对对,就是这意思

varcahr的影响

大佬: 那我看,你上面说,某些情况下,varchar会有影响,是啥情况,啥影响啊?

凯歌: 哦哦哦,这个啊,这个是在排序或者分组的时候,产生的现象,我下面详细说说。

凯歌: 还是拿我们的user表举例子啊,比如,我们要查询user表中id在190万之后的用户的id,姓名,年龄,并且结果要按照年龄排序。SQL语句如下。

sql
复制代码
select id,name,age from user where id>1900001 order by age;

凯歌: 下面我画个图,我们这个SQL的执行流程,大概是什么样子啊。

画板

凯歌: 下面我我照着这个图挑重点讲讲

凯歌: 第一步:InnoDB执行我们的SQL语句,获取到未排序或分组的结果集。

凯歌: 第二步:判断sort_buffer(排序内存缓冲区)的大小,能不能放下我们的结果集

凯歌: 到这里,我们就需要暂停下,分析:怎么判断能不能放下

凯歌: 很简单,一个是看下sort_buffer的大小,一个就是统计每个字段的长度,这时候,因为char存的都是固定且短的字符,而varchar存的是变化且长的字符,如果我们的varchar很长,就放不进sort_buffer

凯歌: 当我们不能把数据都放进内存里的时候,就需要把数据拆开

凯歌: 比如多路并归排序,这时候,我们原本可以一次在内存中操作完的,就需要多次IO操作,增加了成本,降低了性能。

多路并归排序:

将数据拆分成一块块可以放进sort_buffer中的大小,然后一块一块的进去排序,将排好序的数据,再存到磁盘中,等所有的小块,都排好了,再把每一个小块中,最小的主键取出来,然后再根据这些取出来的主键,把整个数据在内存排好,返回给客户端

大佬: 哦哦哦,那我大概明白了。这里的排序、分组啥的还能再展开讲讲不,感觉好多还可以展开再说说。

凯歌: 当然,不可以了! 时间来不及了,马上12点了,这块不是这里的重点,后期我在别的地方单独讲给你听。

大佬: 行吧,你个老六。

单个varchar的最大长度是多少?

大佬: 那不能展开讲那个,你说说一个varchar最多能存多少东西吧,你老说它可变,到底能变多长啊?无限长?

凯歌: 这没问题。

凯歌: 根据mysql的官方文档,我们可以知道一个varcahr的最大长度是65535个字节。如下图:

大佬: 这是它的整体大小,那我们存数据也能存这么多吗?

凯歌: 不不,我们存数据的时候,会略微小一点。

大佬: 那为啥为小啊?存别的东西了?出轨了?

凯歌: 对的,就是存别的东西了,不过没出轨啊,都是存的跟你相关的东西。

凯歌: 这额外存的东西,包含两部分,如下

第一部分:是否null值,占用1字节

第二部分:字符串长度,占用1-2字节,以255为分界线,大于255字节,需要两个字节

凯歌: 也就是说,按照最小可用来说,我们可以存储:65535-1-2=65532字节

大佬: 哦哦哦,65532个字符嘛。

凯歌: 停!不是字符!是字节!

特别提示:字符和字节不同,不同的编码规则,一个字符对应的字节数不一致,例如:UTF-8编码规则,一个字符最大可以占用三个字节

凯歌:以上,就是我们本次关于MySQL 中 varchar 和 char 有什么区别?的讲解了,若有错误,请帮忙指出,一定修改。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
凯歌
下载 APP