作为CRUD开发人员,需要做出的权衡之一是决定在服务器上的SQL中应该完成多少工作,以及在代码中应该在客户端完成多少工作.
你如何决定支点在哪里?您的决定有哪些因素?你犯了什么样的错误?什么效果很好?
[编辑]我对这个问题的回答率很低,我感到很惊讶.我认为这是所有CRUD编程的基本问题.设置余额的是性能和可维护性之间的权衡.
我没有真正考虑的另一个问题是域名变化不大,答案可能需要在每个域的部分表达.这就是我在答案中尝试做的事情.
我的重点:
最小化数据库跳闸.如果可能,代码应该完成大部分工作,并且只在必要时才访问数据库.如果是这样,它应该尽可能多地获得当前操作.
最大限度地减少SQL复杂性.即使我们应该少访问数据库,这并不意味着构建一个过于复杂的SQL查询,这个查询不具备性能并且做得太多.仍然需要维护查询,如果两个更简单的查询将节省开发和维护一个大型查询的麻烦,那么应该使用额外的代码而不是更多的数据库工作.
最小化代码列表迭代.代码很棒.一个放置业务逻辑的好地方,以及许多整洁的库函数.代码很棒.但是,如果使用代码意味着必须通过从数据库返回的列表反复迭代,其中一些简单的数据库where子句或连接可以消除该工作,那么SQL需要得到改进,并且代码最小化.
这通常是个案基础.对于长寿命的应用程序,维护是一项巨大的成本,简单性通常会决定我的设计.
数据库是一个容纳数百万行表的地方,可以有效地对这些表进行读写.
数据库不是执行字符串操作或日期逻辑的地方.它不是计算余额或生成邮件的地方.使用其他工具(例如代码)可以更好地解决这些问题.
任何与数据完整性相关的内容都应该在数据库中完成.原因是数据可能受到多种来源的影响,而不仅仅是用户界面.因此,数据库应存储关键关系,对字段中允许的数据的约束,默认值等.如果约束对于常规约束而言过于复杂,则必须触发.应仔细考虑数据类型,并以某种方式作为约束.如果数据旨在用于数学计算,则应使用某种类型的数值数据类型(不是浮点数或实数),数据是日期,始终使用日期时间数据类型来存储非日期.如果数据是数字但不是用于数学计算(例如SSN),
这并不意味着您在发送之前不应检查它是否是GUI中的有效日期.您应该对GUI发送到数据库的数据执行检查,以避免发送不会插入的数据,但应始终设置数据库以防止插入不正确的数据,无论它是如何发送的.没有任何意义浪费宝贵的网络和数据库资源来处理已知的坏数据.
报告聚合通常可以在GUI上更快地完成,但是如果需要返回太多记录,则最好在数据库端执行,或者您应该创建OLAP报告数据库以提高速度.
这不是SQL与代码问题,而是更多的客户端与服务器问题.客户端/服务器的整体思想是让服务器以集中的方式为客户端提供服务.在实践中,这意味着:
如果服务器可以快速执行,则在服务器上执行此操作
如果服务器可以返回一个小结果,那么在服务器上执行
如果您可以隐藏客户端的复杂性,那么在服务器上执行此操作
涉及的许多问题都可以在其他设计领域找到,例如面向对象的设计.为其他类提供服务的类应该封装功能,并且只公开其客户端所需的内容.SQL服务器也是如此.如果您认为SQL服务器仅仅是一个数据检索系统,那么您就没有采取适当的优势.
实际节省包括:最小化通过网络发送的数据; 集中/标准化处理; 允许更改而无需重新部署客户端软件; 改善了表现.
至于准确划线的地方......没有神奇的答案.真正的答案是数据库模式+存储过程+视图定义了一个API,良好的API设计并非易事,但值得麻烦.使用信息隐藏,封装,内聚以及您在其余编程和设计工作中使用的所有其他内容等原则.他们在这里很合适.