共计 3058 个字符,预计需要花费 8 分钟才能阅读完成。
关注 “Java 后端技术全栈 ”**
回复“面试”获取全套大厂面试材料
因为近期工作波及数据库相干的操作较多,就依据本人的实战经验整顿了一些数据库开发的标准用法,利用 6 个“防止”来概括。
1、防止在数据库中做运算
有句话叫做“别让脚趾头想事件,那是脑瓜子的职责”,用在数据库开发中,说的就是防止让数据库做她不善于的事件。MySQL 并不善于数学运算和逻辑判断,所以尽量不在数据库做运算,简单运算能够移到程序端 CPU。
2、防止对索引列做运算
有次,有位共事让我看一条 SQL,说是在前台查问很快,然而把 SQL 取出来,在数据库中执行的时候,跑 10 分钟都不出后果。
看了一下 SQL,最初定位到一个视图中的一个子查问下面。该子查问的 SQL 文本如下:
SELECT acinv_07.id_item ,
SUM(acinv_07.dec_endqty) dec_endqty
FROM acinv_07
WHERE 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 的玩法