在日常开发中,我们为了书写代码方便、快捷,经常在SQL的SELECT语句中使用通配符(*)来查询一张表中的所有列的信息。在一般情况下使用通配符的确会很方便,但是也会给你带来非常难以发现的错误。如:有A和B两表,它们都有c_name字段,你想通过A JOIN B,来查找B表中所有有c_name字段的行(实际返回的是B表的c_name字段),但是返回的数据与你想要的数据不匹配。下面我们来看看使用通配符会给我们带来那些常见问题以及解决这些问题的方法。
A表结构和B表结构如下所示:
-- A表 create table A ( n_id int not null primary key, c_name varchar(100), n_age int, n_classId int -- 外键B.n_id ); -- B表 create table B ( n_id int not null primary key, c_name varchar(100), n_count int );
常见问题:
1、破坏代码重构
假设你有如下SQL语句:
-- id, c_name, n_age, n_classId insert into a values(1, 'Tom', 23, 12);
但是,数据库A表由于业务需要添加了c_email字段,此时上面的SQL语句将会出现错误。因此通过下面方式就不会存在上面的问题:
insert into a(id, c_name, n_age, n_classId) values(1, 'Tom', 23, 12);
假设你有如下查询SQL语句:
select * from a;
你可以通过数据库表A定义时表字段的顺序进行访问,但是由于业务需要将某列删除了,那么原来列的顺序就发生了改变。如:原来c_name列下标是2,删除列后变为1,你在用下标为2的去访问,可能会出错,也可能取出的值并非c_name的值。因此建议修改如下:
select n_id, c_name, n_age, n_classid from a;
2、开销问题
我们知道使用SQL语句的通配符会将指定数据表中所有的列都获取出来,如果该数据表中存在blob列,而且该列中存在用户图片的二进制信息,或者该数据表非常的大(包含几百个字段),然而你自需要一小部分的字段。如果每次请求你都将所有的数据返回出来,然后传递个客户端,这会造成网络资源的浪费,计算机资源浪费(如果采用ROM进行映射,所有被查询出来的字段都需要通过Java的反射机制进行设置)。
推荐做法
1、明确列出你所需要的列名称,这就能够避免上面出现的问题。而且即使表被修改了,也会很快的找出要修改的地方,有时甚至不用做出任何修改操作。
2、你不需要的列不要查询出来,这样可以节省计算机资源、网络资源等。即使是一个字段,如果一个字段一天被请求上万次,那么一年下来也是不少的资源浪费。
3、不要为了方便而是用通配符,建议你放弃通配符,通配符对你没有好处的。