关注“Java后端技术全栈”**
回复“面试”获取全套大厂面试材料
因为近期工作波及数据库相干的操作较多,就依据本人的实战经验整顿了一些数据库开发的标准用法,利用6个“防止”来概括。
1、防止在数据库中做运算
有句话叫做“别让脚趾头想事件,那是脑瓜子的职责”,用在数据库开发中,说的就是防止让数据库做她不善于的事件。MySQL并不善于数学运算和逻辑判断,所以尽量不在数据库做运算,简单运算能够移到程序端CPU。
2、防止对索引列做运算
有次,有位共事让我看一条SQL,说是在前台查问很快,然而把SQL取出来,在数据库中执行的时候,跑10分钟都不出后果。
看了一下SQL,最初定位到一个视图中的一个子查问下面。该子查问的SQL文本如下:
SELECT acinv_07.id_item , SUM(acinv_07.dec_endqty) dec_endqtyFROM acinv_07WHERE acinv_07.fiscal_year * 100 + acinv_07.fiscal_period = ( SELECT DISTINCT ctlm1101.fiscal_year * 100 + ctlm1101.fiscal_period FROM ctlm1101 WHERE flag_curr = 'Y' AND id_oprcode = 'acinv' AND acinv_07.id_wh = ctlm1101.id_table)GROUP BY acinv_07.id_item
在acinv_07表上的列fiscal_year和列fiscal_period是有索引的。然而,如果对索引列进行运算,就会导致本来能够走索引的走不了索引。于是,入手改写成如下SQL:
SELECT id_item , SUM(dec_qty) dec_qty FROM dpurreq_03 GROUP BY id_item ) a , ( SELECT a.id_item , SUM(a.dec_endqty) dec_endqty FROM acinv_07 a , ( SELECT DISTINCT ctlm1101.fiscal_year , ctlm1101.fiscal_period , id_table FROM ctlm1101 WHERE flag_curr = 'Y' AND id_oprcode = 'acinv' ) b WHERE a.fiscal_year = b.fiscal_year AND a.fiscal_period = b.fiscal_period AND a.id_wh = b.id_table GROUP BY a.id_item
再执行,4s钟左右就能够跑出后果了。
总的来说,写SQL时,不到万不得已,不要对索引列进行计算。
3、防止count(*)
在分页查问的时候,有的人总是习惯用select count()取得总的记录条数,实际上这不是一个高效的做法,因为,之前取得数据的时候曾经查问过一次了,select count()相当于同一个语句查问了两次,对数据库的开销天然就大了,咱们该当应用数据库自带的API,或者零碎变量来实现这个工作。
4、防止应用NULL字段
大家在数据库表字段设计的时候,应该尽量都加上NOT NULL DEFAULT ''。
应用NULL字段会产生很多不好的影响,例如:很难进行查问优化、NULL列加索引,须要额定空间、含NULL复合索引有效……
看上面的案例:
数据初始化:create table table1 ( `id` INT (11) NOT NULL, `name` varchar(20) NOT NULL)create table table2 ( `id` INT (11) NOT NULL, `name` varchar(20))insert into table1 values (4,"zhaoyun"),(2,"zhangfei"),(3,"liubei")insert into table2 values (1,"zhaoyun"),(2, null)
(1) NOT IN子查问在有NULL值的状况下返回永远为空后果,查问容易出错
select name from table1 where name not in (select name from table2 where id!=1)
(2) 列值容许为空,索引不存储null值,后果集中不会蕴含这些记录。
select * from table2 where name != 'zhaoyun'
select * from table2 where name != 'zhaoyun1'
(3) 应用concat拼接时,首先要对各个字段进行非null判断,否则只有任何一个字段为空都会造成拼接的后果为null
select concat("1", null) from dual;
(4) 当计算count时候null column不会计入统计
select count(name) from table2;
5、防止select *
- 应用select *可能会返回不应用的列的数据。它在MySQL数据库服务器和应用程序之间产生不必要的I/O磁盘和网络流量。
- 如果明确指定列,则后果集更可预测并且更易于治理。设想一下,当您应用select *并且有人通过增加更多列来更改表格数据时,将会失去一个与预期不同的后果集。
- 应用select *可能会将敏感信息裸露给未经受权的用户。
6、防止在数据库里存图片
图片的确是能够存储到数据库里的,例如通过二进制流将图片存到数据库中。
然而,强烈不倡议把图片存储到数据库中!!!!首先对数据库的读/写的速度永远都赶不上文件系统解决的速度,其次数据库备份变的微小,越来越耗时间,最初对文件的拜访须要穿梭你的应用层和数据库层。
图片是数据库最大的杀手。一般来说数据库都是存储一个URL,而后再通过URL来调用图片。
图片,文件,二进制数这三样货色谨慎存储到数据库中。
举荐浏览
【原创】SpringBoot疾速整合Thymeleaf模板引擎
【原创】Spring Boot 集成Spring Data JPA的玩法
【原创】Spring Boot集成Mybatis的玩法