Jaccorot 日事日毕日清日高

ARTS-013

2020-09-10

一、Algorithm

二、Review

三、Tip

四、Share

varchar 和char

区别

  • char是定长的,插入数据不足规定长度的,右边补空格,当然查询出来的数据也会有空格,插入数据超过规定长度,会返回错误[22001][1406] Data truncation: Data too long for column ‘name’ at row 1,MySQL并不会自动截短字符串。因为char是定长的,所以查询的效率比varchar高(后面会将为什么效率高),但在列容量不能充分利用的情况下会造成一定的空间浪费。

  • varchar是不定长的,varchar类型的列是不定长的。插入的数据超过设置的长度时,超出的部门将会被截取。

在mysql 5.0版本以后的最大长度是65536字节(2^16),但是这个长度只是“系统长度”,这并不意味着你真的可以完全利用65536字节来存储数据,因为varchar是不定长的,所以需要前两个字节标记字段的实际长度,结尾还要用一个字节表示结束,在减去头尾的”系统”占用字节后,只剩下65533可用字节。

那么我们建表的时候,能不能直接写varchar(65533)呢?

当然是不可以的,因为4.0之后,varchar后面的小括号里就不再是字节长度了,而是字符长度。

  • 编码 长度
    utf8 65533/3=21844(汉字占3个字符)
    utf8mb4 65533/4=16383(汉字占4个字符,包含了生僻汉字和文字表情)

那么这是否意味着,在utf8mb4编码下我们可以用varchar(16383)来定义一个列呢?

答案是要看情况,MySQL规定了一个row所有的字段加起来总长度不能超过65535字节,所以如果一个表只有一个列,那完全可以用varchar(16383)来定义这个列。如果这个表还有其他列,无论其他列多么短,都是会占用字节数的,所以,使用varchar(16383)来定义的时候,MySQL会返回错误提示:ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs,意思是row的容量太大,超出了row的最大容量65535,如果不改变列的长度的话,推荐使用TEXT or BLOBs类型。

应用场景

为什么char类型查询效率高

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

应用

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

总结

  • 区别一,定长和变长 char 表示定长,长度固定,varchar表示变长,即长度可变。char如果插入的长度小于定义长度时,则用空格填充;varchar小于定义长度时,还是按实际长度存储,插入多长就存多长。

因为其长度固定,char的存取速度还是要比varchar要快得多,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以会占据多余的空间,可谓是以空间换取时间效率。varchar则刚好相反,以时间换空间。

  • 区别之二,存储的容量不同 对 char 来说,最多能存放的字符个数 255,和编码无关。

而 varchar 呢,使用额外的1-2字节来存储值长度,最多能存放 65532 个字符。varchar的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是 65,532字节。

  • 区别三 空格处理 varchar5.0以上版本,取值或设置值都会保存字符串末尾的空格,4.1之前的版本都会把字符串末尾的空格删除掉。 char保存的时候会去掉字符串末尾的空格。

Similar Posts

上一篇 ARTS-012

下一篇 ARTS-014