为什么《一个程序员怎么能做出这样的事情》?
今天在《外刊IT评论》里面看到这样一篇文章 《一个程序员怎么能做出这样的事情》 ,觉得作者的观点非常有意思,下面看看文章中的一段代码
public void Execute() { ArrayList empIds = PayrollDatabase.GetAllEmployeeIds(); foreach (int empId in empIds) { Employee employee = PayrollDatabase.GetEmployee(empId); if (employee.IsPayDate(payDate)) { DateTime startDate = employee.GetPayPeriodStartDate(payDate); Paycheck pc = new Paycheck(startDate, payDate); paychecks[empId] = pc; employee.Payday(pc); } } }
这一段代码是非常有名的大师写的,是在Robert C(敏捷软件开发理论的创始人)那里。他的《敏捷软件开发:原则、模式与实践(C#版)》这边书里。是的,是 Robert C。Martin,也就是Uncle Bob。
该文作者认为应该一次性查询所有的雇员信息,而不是查询出来所有的ID,然后根据ID获取一条条的查询雇员信息。至于怎么样,还是需要看当时的上下文环境,不过大多数情况下,该作者看法是没有太大的问题的,但是有一些特别的情况我们需要也需要考虑一下:
1 假设单个雇员的信息量比较大,也就是字段数比较多,并且一次查询返回10W条记录,这样情况下,采用那种方式就需要考虑了
分析以下,假设一个雇员所有信息对象是10K大小,简单按照0.01M计算,10W的数据量大小大概是100M,这样一次查询就有100M数据需要短时间内从数据库传输到应用程序,会占用大量带宽,如果这样的请求比较多,而且是并发请求,由于需要大量带宽传输数据,数据库的压力回比较大,而且影响其他的数据库查询操作。在应用程序服务器里面,100M的数据缓存在内存里面,如果这样的查询请求过多,那么就很容易造成内存溢出。
2 假设单个雇员的信息会更新的比较频繁,那么 一次性先查询所有的雇员信息,可能在处理的时候,雇员的信息就发生了变化,导致结果可能会有比较大的误差。所以先查询id,然后处理的单条数据的再去查询一下数据库,避免数据在第一次查询和第二次查询之间发生的变化。
3 假设处理个雇员信息的时候考虑到安全原因,需要对雇员信息进行加锁处理,那么我们不应该对数据批量加锁,对单条数据加锁会是一个比较好的选择。比如假设给雇员发工资,为了防止多个线程同时对雇员发工资,进行更新操作线程必须锁住单个雇员信息。
当然了,上面几种情况大部分场景可能并不是比较常见的场景,但是作者所说的处理逻辑在任何环境下不一定都是正确的,还是要对具体情况做具体分析。