日常开发中如何减少bug?将从数据库、代码层面、缓存使用篇
纯情博客为您提供最新网络安全黑客博客信息资讯
前言
今天就和大家聊一聊如何在日常开发中减少 bug? 本文将从数据库、代码层面、缓存使用三大方向总结共计 50 多个关注点,帮助大家成为开发品质之星。
1. 数据库
慢查询
数据库章节,哪些地方容易出 bug? 我总结了 7 个方面:慢查询、数据库字段注意点、事务失败场景、死锁、主从延迟、新旧数据兼容、一些 SQL 经典注意点。
1.1 慢查询
慢查询 .gif1.1.1 是否命中索引
说到慢查询,我们马上就会想到索引。 如果一个 SQL 没有索引,或者没有命中索引,就会产生一个慢查询。
什么情况下索引会失效?
1.1.2 数据量大,考虑分库分表
如果单表数据量过大脚本源码,会影响 SQL 执行的性能。 我们知道,索引数据结构一般是 B+ 树,一棵高度为 3 的 B+ 树可以存储大约 2000 万条数据。 如果超过这个数,B+ 树会变高,查询性能会下降。
因此,当数据量较大时,建议将数据库分表。 分库分表的中间件包括 mycat、-jdbc
1.1.3 不合理的 SQL
在日常开发中,笔者见过很多不合理的 SQL:比如一条 SQL 居然用了 6 个表连接,表太多会影响查询性能; 又比如一张表,实际上加了 10 个索引等,索引会降低插入和更新 SQL 的性能,所以一般不建议索引太多,一般不要超过 5 个。
1.2 数据库字段注意事项
数据库字段的内容容易出现 bug。 比如你在测试环境修改了表结构,增加了某个字段,生产环境忘记带脚本,那肯定是版本有问题。
1.2.1 字段是否会过长
假设您的数据库字段是:
如果请求参数自带变量名,字段长度为 300,插入表时会报错。 因此需要对参数进行校验,防止字段过长。
1.2.2 如果字段为空,会不会造成空指针等
我们在设计数据库表字段的时候,尽量把字段设置为 not null。
如果数据库字段设置为 NULL 值,很容易导致程序出现空指针; 如果数据库字段设置为 NULL 值,需要注意使用 count(特定列),会有陷阱。
1.2.3 缺失字段
对于我们日常的开发任务,如果我们在测试环境修改表,比如增加新的字段,我们必须把 SQL 脚本带到生产环境,否则字段会丢失,发布时就会出现问题。
1.2.4 字段类型是否支持表情
如果表字段需要支持表达式存储,使用 .
1.2.5 谨慎使用文本和 blob 字段
如果您要在字段中存储文件,请考虑存储文件的路径而不是保存整个文件。 使用文本时,注意在查询条件时创建前缀索引。
1.3 事务失败的场景 1.3.1 @ on non-
@注解,添加到非修饰方法时,事务不会生效。 事务是基于 AOP 的思想,也是通过动态代理实现的。 事务本身在调用动态代理之前,已经过滤了非方法,所以非方法,事务不会生效。
1.3.2 本地方法直接调用
在下面的场景中,@ 也是无效的
1.3.3 异常被 try...catch 吃掉,导致事务失败。
1.3.4 属性设置错误
默认抛出未检查异常(继承异常)或 Error 来回滚事务; 其他异常不会触发回滚事务。 如果事务中抛出其他类型的异常,则需要指定该属性。
1.3.5 底层数据库引擎不支持事务
存储引擎不支持事务,支持事务
1.3.6 事务和业务逻辑代码必须在一个线程中
业务代码必须和事务的源码在同一个线程中才能被事务控制。 比如下面的代码,方法的子线程,内部的事务操作都不会被方法上的事务控制。 每个人都应该注意这一点。 这是因为在事务实现中使用它来实现同一个线程中的数据共享。
1.4 死锁
死锁是指两个或多个事务在同一个资源上相互占用 wordpress 插件,并请求锁定对方的资源,从而形成恶性循环的现象。
MySQL 内部有一套死锁检测机制。 一旦发生死锁,它会立即回滚一个事务,让另一个事务继续执行。 但是带数据库的网站源码,死锁存在资源利用率降低、进程无法获得正确结果等危害。
1.4.1 SQL 锁 9 种情况分析
为了避免死锁,你需要学会分析:SQL 锁是如何工作的? 可以在九种情况下讨论 SQL 锁:
1.4.2 如何分析和解决死锁?
分析和解决死锁的步骤如下:
有兴趣的朋友可以看看我之前写的这篇文章:教你分析 Mysql 死锁问题
1.5 主从延时注意事项
先插入,后查询。 这种代码逻辑比较常见,可能会有问题。 一般数据库有主库和从库。 写是写到主库,读一般是从库读。 如果出现主从延时,很有可能你已经插入成功,但是无法查询。
1.5.1 需要强一致性,考虑阅读主库
如果是重要业务,需要强一致性,考虑直接读主库
1.5.2 不需要强一致性,从库中读取
如果是一般业务,可以接受暂时的数据不一致,优先从库读取。 因为从库可以分担主库的读写压力,提高系统吞吐量。
1.6 新旧数据兼容 1.6.1 新增字段,考虑股票数据默认值
在我们的日常开发中,随着业务需求的变化,我们经常需要在某个数据库表中添加一个字段。 比如在一个 APP 配置表中,需要增加一个场景编号字段,比如它的枚举值为 01、02、03,那么我们要和业务对齐,新增的字段,默认值是多少旧数据的,是空的还是默认 01。如果是 NULL,程序代码必须处理空指针。
1.6.2 如果新业务使用旧字段,考虑旧数据的值是否有坑
如果开发时需要继续使用数据库表的老字段,有股票数据,就需要考虑老股票数据库的值是否存在陷阱。 比如我们的表中有一个字段。 在旧数据中,它的枚举值为 01:超级管理员 02:管理员 03:普通用户。 假设业务需求是一般用户分为 03 查询用户和 04 操作用户,那我们在开发的时候就得考虑旧数据值的问题。
1.7 一些经典 SQL 注意点 1.7.1 限制大分页问题
limit large 是一个非常经典的 SQL 问题,我们一般都有这三种对应的解决方案
方案一:如果 id 是连续的,可以返回上次查询的最大记录(偏移量),然后往下限制
选项 2:如果业务允许,限制页数:
建议和业务商量,最后是否需要检查分页。 因为绝大多数用户是不会翻太多页的。 搜索页面也限制了页面数量,所以不存在限制大分页的问题。
方案三:使用延迟关联或者子查询来优化超多分页场景。 (先快速定位到需要获取的 id 段,再进行关联)
1.7.2 当修改和查询大量数据时,考虑批处理。
我们在更新或者查询数据库数据的时候,尽量避免循环操作数据库,可以考虑分批进行。 比如要插入 10 万条数据,一次插入 500 条带数据库的网站源码,执行 200 次即可。
正例:
反例: