MySQL里的char和varchar有什么区别?
首先是存储长度的不同,char类型在创建表的时候就固定分配好了长度和存储空间,分配多少空间将会占用多少空间,可以设置的最大长度为char(255),当创建好char列之后,如果存储的实际数据没有达到设置的长度,MySQL会在数据后面默认使用空格填充。在读取数据的时候,MySQL会将字符后面多余的空格字符自动移除,(如果开始了PAD_CHAR_TO_FULL_LENGTHSQLMODE不会移除空格)。
varchar类型的数据列是可变长度的字符列,varchar可以设置的最大长度是varchar(65535),但是因为MySQL单行记录数据的localpage最大限制为65535字节(不含offpage),varchar列的长度设置也不能超过这个限制,即一行数据的所有列总大小不能超过65535字节。varchar类型的列因为存储时不会自动填充空格,所以在查询时也是原样检索,不过会过滤数据后面的空格。
varchar会额外占用1-2字节来存储额外的内部结构数据,具体额外占用1字节还是2字节取决于varchar设置的长度,如果设置的字符长度小于等于255,那么占用1字节,如果设置的长度大于255,那么占用2字节。
如果数据库的SQLMODE开启了严格模式(StrictSQLMODE),向char,varchar列写入一个超过了当前列设置的最大长度,那么数据库将返回Error,写入失败。但是当关闭了严格模式时,写入会返回成功,超过列长度的字符将会被截断,数据库返回一个警告值(Warning)。
以下表格可以看出char和varchar存储数据格式和存储长度需求的差别。其中最后一行数据可以看到超过了设置的长度,数据被截断,当SQLMODE设置为严格模式下的时候,最后一行数据将无法写入,数据库返回Error。
Value | CHAR(4) | Storage Required | VARCHAR(4) | Storage Required |
'' | ' ' | 4 bytes | '' | 1 byte |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
MySQL的Innodb特性里面,会将固定长度的字段(不包含varchar、text、blog等字段)编码后计算,如果超过768字节,那么会转换成可变长度的类型进行存储,会将超过768字节的数据存储到off-page中,剩余的存储到record-page中。例如我们建了一个字段类型char(255),如果这个字段的编码为utf8mb4字节,那么就超过了768字节,就或转换为可变长度的类型使用到off-page存储。
![d5802eb4751e58188571b8394e2df82d.png](https://i-blog.csdnimg.cn/blog_migrate/50030e49f909e4019edfdcae0e8e1a0b.png)
总结备忘录:
char类型在字段创建时默认分配所有空间,最大支持255个字符,即varchar(255)。
varchar类型不默认分配空间,使用多少分配多少,最大支持长度为varchar(65535),但是受限于innodb单行记录不超过65535字节的限制。
char类型在数据写入时如果数据长度没有写满,会使用空格填充,读取的时候会自动过滤空格,varchar类型不会自动填充空格和过滤空格。
如果SQL MODE开启了严格模式(Strict SQL MODE),那么如果写入数据超过设置长度,则会报错,如果没有开启严格模式,那么数据会被截断写入,并且返回一个warning。
char字段类型如果字节数超过768,比如varchar(255)的utf8mb4编码字段,那么内部会转换成可变长度类型,将超过768的字节存储到off-page中。
号外:数据技术架构微信群现已开通,目前已连接各互联网企业数据库、大数据、架构同学100余人,不定时进行干货分享,如果您有兴趣加入讨论,欢迎扫码加入。(或添加群主微信号Andrew_ru拉你入群)