【SQL server 】中 char 类型对查询的影响

今天遇到了一个关于char类型的问题,感觉非常值得注意,所以写下这篇文章,用于总结。


先来看问题:

在数据库中创建两张表,两张表中插入完全相同的数据,不同点在于Sname字段的数据类型不同,一个是char(20)另一个是varchar(20)

但是当我用相同的语句进行模糊查询时select Sname from StudentA where Sname like '欧阳_';
却得到了截然不同的结果,这是什么原因呢??


create table StudentA
(
	Sno char(10) primary key
	,Sname `char(20)` not null
);
insert into StudentA values('2018110601','欧阳');
insert into StudentA values('2018110602','欧阳洋');
insert into StudentA values('2018110603','欧阳洋洋');

select Sname from StudentA where Sname like '欧阳_';//结果如下
//     | Sname
//  1  | 欧阳                
//  2  | 欧阳洋              
create table StudentB
(
	Sno char(10) primary key
	,Sname `varchar(20)` not null
);
insert into StudentB values('2018110601','欧阳');
insert into StudentB values('2018110602','欧阳洋');
insert into StudentB values('2018110603','欧阳洋洋');

select Sname from StudentA where Sname like '欧阳_';//结果如下
//     | Sname
//  1  | 欧阳洋                   

这是因为:char类型的长度是固定的,当长度不够是会自动补齐空格,varchar的长度是可变的,多余的长度会自动收缩。

关于空格的一些细节,后面会进行详细介绍,这里不再赘述。

这就表示,使用char(10)存储字符串'abc'时,实际上是这样的:‘abc _______’,字符串将占10个字节(包括7个空字符);
而使用varchar(10),则表示只占3个字节‘abc’,10是最大值,当存储的字符小于10时,按照实际的长度存储。


所以,在第一个表StudentA中,每一条记录的Sname字段实际上是这样存储的:(因为每个汉字占用2个字节)
‘欧阳________________’字符串占20个字节(所以还包括16个空字符);
‘欧阳洋______________’字符串占20个字节(所以还包括14个空字符);
‘欧阳洋洋____________’字符串占20个字节(所以还包括12个空字符);

而,在第二个表StudentB中,每一条记录的Sname字段实际上是这样存储的:(因为每个汉字占用2个字节)
‘欧阳’字符串占4个字节;
‘欧阳洋’字符串占6个字节;
‘欧阳洋洋’字符串占8个字节;


这样一来,在进行select Sname from StudentA where Sname like '欧阳_';查询时,后面的空格也会被计入其中,所以

第一个表(char)的查询结果为:

select Sname from StudentA where Sname like '欧阳_';//结果如下
//     | Sname
//  1  | 欧阳                
//  2  | 欧阳洋   

第二个表(varchar)的查询结果为:

select Sname from StudentA where Sname like '欧阳_';//结果如下
//     | Sname
//  1  | 欧阳洋        

总结一下:

1. 在长度固定或者长度较短时可以使用char。(列如身份证号码、邮政编码、手机号码)

2. 经常被修改的字段,为了效率应当考虑用char代替varchar(列如一个用户的名字经常被修改)

3. 密码字段不能使用char,空格会影响查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值