Mysql char 和 varchar 的区别
char 和 varchar 类型相似,都是用来存储字符串,但是它们 存储 和 检索 的方式不同,char 属于固定长度的字符类型,而 varchar 属于长度可变的字符类型
一、准备数据
创建一张 test 表,建表语句如下
CREATE TABLE `test` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键 id',
`firstName` char(5) NOT NULL DEFAULT '' COMMENT '姓氏',
`lastName` varchar(5) NOT NULL DEFAULT '' COMMENT '名字',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
firstName 类型是 char(5),lastName 类型是 varchar(5),那么我们就开始探究一下它们之间到底有什么区别
二、存储时的区别
先看一下不同长度的字符串在 char(5) 和 varchar(5) 中存储所需要占用磁盘空间的大小
字符串值 | char(5) | 存储占用磁盘空间大小 | varchar(5) | 存储占用磁盘空间大小 |
'' | '' | 5 个字节 | '' | 1 个字节 |
' ' | ' ' | 5 个字节 | ' ' | 2 个字节 |
'abc' | 'abc' | 5 个字节 | 'abc' | 4 个字节 |
'abcde' | 'abcde' | 5 个字节 | 'abcde' | 6 个字节 |
'abcdefg' | 'abcde' | 5 个字节 | 'abcde' | 6 个字节 |
先解释一下上面这张表
为什么 varchar 类型存储占用磁盘空间大小这一列比实际的字符长度多 1 个字节呢?(例如字符串 'abcde' 存储时需要 6 个字节)
因为 varchar 类型是长度可变的,它需要额外的 1 个或者 2 个字节来记录当前存储的字符串长度,当字符串的长度 小于等于255 时,这个额外的长度就是 1 个字节 ,当字符串长度大于 255 时,额外长度就是 2 个字节
char(5) 和 varchar(5) 是表示最多能存储 5 个字节长度的字符串,在 非严格模式 下,如果插入字符串 'abcdefg' ,char(5) 和 varchar(5) 都只会截取最大能存储的长度进行存储,最终存储的结果都是 'abcde',如果是在 严格模式 下,则会插入失败
三、检索时的区别
查询时 char(5) 和 varchar(5) 获取到的值并不是相同的,现在我们尝试插入几条数据
insert into test (firstName, lastName) VALUES ('','');
insert into test (firstName, lastName) VALUES (' ',' ');
# abc 前后都没有空格
insert into test (firstName, lastName) VALUES ('abc','abc');
# abc 前面有空格
insert into test (firstName, lastName) VALUES (' abc',' abc');
# abc 后面有空格
insert into test (firstName, lastName) VALUES ('abc ','abc ');
# abc 前后都有空格
insert into test (firstName, lastName) VALUES (' abc ',' abc ');
insert into test (firstName, lastName) VALUES ('abcde','abcde');
接着来查询一下数据
发现什么规律没,Mysql 在对 char 和 varchar 类型检索时,对于包含空格的时候,有如下处理规则,这个需要注意一下
char : 不会去掉前面的空格,但是会去掉后面的空格
varchar : 既不会去掉前面的空格也不会去掉后面的空格
四、总结
1、char 类型是固定长度的,Mysql 在程序处理的时候不需要计算长度,所以它的速度比 varchar 要快,但是其缺点是浪费存储空间,插入时如果长度不够会在尾部以空格填充,查询时 Mysql 程序会对尾部的空格进行处理,浪费性能,综合来说,如果业务需求中字段长度变化不大的情况下使用 char 类型来存储(例如 性别 字段,不是 0 就是 1,可以设计成 char(1) )
2、在使用 varchar 类型的时候不能因为其长度可变就都为 varchar 定义一个很大的长度,实际开发中仍然要根据业务需求来设计合适的长度,定义一个远超实际需求长度的字段可能会影响 Mysql 程序的性能,并且还有可能出现一些未知的 BUG,所以设计 varchar 类型的长度时,一定要根据业务需求去评估,选择一个合适的长度