在开始讨论之前先提出两个关于查询的问题。分别如下:
第一个问题:
假如有两张表student和user,它们其中都有name列,其中user表中的name大部分为空。有如下查询:
select * from student s join user u on s.id=user.id;
打印出来的name列全为空
第二个问题:
怎样在使用通配符(*)后给一列取别名。代码如下:
select *, name as c_name from student;
从上面的两个问题我们可以看出开发人员就是不愿意多巧字。所以才使用了通配符(*)。如:
select c_name, c_sex, n_age, d_birthday, c_address from student;
使用通配符后(*),如:
select * from student;
看上去的确简单了不少。但是这会给你带来想不到的后果。下面将详细讨论
通配符带来的问题:
1、破环代码重构
问题一:
假设你使用如下语句向student表中插入学生信息:
insert into student values('张三', '男', '汉族', 25);
后来新增加了一列(如:住址),此时你的插入语句就出现了错误,因为student表有5列,而你只有4个参数。
问题二:
如果你使用如下语句检索学生信息:
// 假如列的顺序是:姓名、性别、民族、年龄 Row row = select * from student; String sex = row[1]; // 性别
后来在student表中"姓名"列后面添加了"地址"列,则row[1]取出就不是"性别"了,而是"地址"。类似这种错误是很难发现了。
2、浪费带宽
假如你做了一个查询,这个查询返回student表中的所有数据(使用了通配符)且student表中包含了很多关于学生的信息,包含:姓名、年龄、头像等信息,每一条学生信息大概为4kb大小,实际用到了1kb。该查询每一分钟需要调用100次。那么一小时需要的宽带如下:
N = 60分钟 * 4KB;
如果宽带不是很大且访问也非常大,则会造成更多的资源浪费,加大流量开销。
解决办法(推荐):
1、明确列出列名。如:
select a.name, a.age, a.sex from test;
2、预防错误(1的好处)。
a、如果列的位置被移动,则不会对已有的SQL造成影响。
b、如果插入新列,则不会出现在结果集中;
c、如果删除一列,则查询会报错误(可以迅速定位错误)
3、你不需要它(不需要的列就不要出现在select的列表中,这样可以节约带宽和提速)。