char和varchar的区别

在MySQL中,char和varchar可能是我们最常使用字符串类型。那么到底varchar和varchar有什么不同?我们什么时候使用char,什么时候使用varchar呢?

char

cahr是定长的,插入数据不足规定长度的,右边补空格,当然查询出来的数据也会有空格,插入数据超过规定长度的,会报错,因为mysql并不会自动截短字符串。因为char是定长的,所以查询效率比varchar高,但是对于分配的长度不能充分利用的情况下会造成一定的空间浪费

varchar

varchar是不定长的,varchar类型的列是不定长的,在5.0版本以后最大长度为65536个字节(2^16),但是这个长度只是系统长度,并不意味着你真的可以完全利用65536字节来存储数据,因为varchar是不定长的,所以需要前两个字节标记字段的实际长度,结尾还要用一个字节表示结束,者可以用u盘来说明,买一个256G的u盘,但是实际并不足256G,因为系统也要占用一部分。

需要注意的是65535只是字节个数,而且是理论字节个数,在减去头尾系统占用字节后,只剩下65533可用字节。那么我们建表的时候,能不能直接写varchar(65533)呢?当然是不行的,在4.0版本之后,varchar后面的小括号里就不再是字节长度了,而是字符长度

为什么char类型查询效率高
这是由他们在磁盘上存放的不同形式决定的,我们先来看一个图:
在这里插入图片描述

我们可以看到char类型在存放数据的时候,中间是没有间隔的,数据本身是有空格的,但是数据段之间没有间隔,因为我们在创建列的时候已经告诉MySQL列的长度了,MySQL在查询数据的时候,只需要按部就班寻找就行了,不需要在中途计算这个数据段的长度。
但是varchar类型的存放就不同了,在每个数据段开头,都要有一段空间(1~2个字节)存放数据段的长度,在数据段的结尾还有一段空间(1个字节)标记此字段的节数。MySQL在读取一个数据段的时候,首先要读开头,比如读到了3,说明数据段的长度是3,之后就不多不少,只读3个字节。所以MySQL在遍历数据的时候,磁针要比char类型的列多读很多次磁盘来获取字段的真实长度,这就是为什么varchar比char查询效率低的原因了。

区别:定长和不定长

  1. 当插入的字符长度超出时,如果是严格模式,则会拒绝插入并提示错误信息,如果是宽松模式,则会截取然后插入。如果插入的字符串小于定义长度时,则会以不同方式进行处理,如char(10)表示存储10个字符,无论插入是多少,都是10个,如果少于10个则用空格填满。而varchar(10)小于10个,则插入多少字符就存多少。varchar怎么知道所存储字符串的长度呢?实际上,对于varchar字段来说,需要使用一个(如果字符串长度小于255)或两个字节(长度大于255)来存储字符串的长度。
  2. 对char来说,最多能存放的字符个数 255,和编码无关。
    而varchar呢,最多能存放 65533 个字符。
    VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,533字节
    最大有效长度是 65533 字节,在varchar存字符串的时候,第一个字节是空的,不存任何的数据,然后还需要两个字节来存放字符串的长度。所以有效长度就是 65536 - 1 - 2 = 65533
    注意,char和varchar 后面的长度表示的是字符的个数,而不是字节数

应用
我们可以用varchar存放不定长的数据,比如人的名字,或者一篇博客的文章。可以用char存放定长的数据,比如身份证号和手机号,我们把一个列定义为mobile varchar(11),中国大陆的手机号最长,达到11位,香港是8位,瑞士是10位,所以定义成11位完全够用,可以存放各国的手机号了。

额外说明下,我们在定义字段最大长度时应该按需分配,提前做好预估。特别是对于VARCHAR字段,有人认为反正VARCHAR数据类型是根据实际的需要来分配长度的,还不如给大一点呢。但事实不是这样的,比如现在需要存储一个地址信息,根据评估,只要使用100个字符就可以了,我们可以使用VARCHAR(100)或VARCHAR(200)来存储,虽然它们用来存储90个字符的数据,其存储空间相同,但是对于内存的消耗是不同的。更长的列会消耗更多的内存,因为MySQL通常会分配固定大小的内存块来保存内部值,尤其是使用内存临时表进行排列或者操作时会特别糟糕。所以我们在分配VARCHAR数据类型时仍然不能够太过于慷慨。还是要评估实际需要的长度,然后选择一个最长的字段来设置字符长度。如果为了考虑冗余,可以留10%左右的字符长度。千万不能认为VARCHAR是根据实际长度来分配存储空间,而随意的分配长度,或者说干脆使用最大的字符长度。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季布,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值