我坚信尽可能将业务逻辑排除在数据库之外。但是,作为我公司的绩效开发人员,我赞赏有时有必要取得良好的绩效。但是我认为这比人们声称的要少得多。
我对您的利弊有异议。
您声称它集中了您的业务逻辑。相反,我认为它分散了权力。在我目前正在研究的产品中,我们将存储过程用于许多业务逻辑。我们的许多性能问题来自反复调用函数。例如
select <whatever>
from group g
where fn_invoker_has_access_to_group(g.group_id)
这种方法的问题是通常(在某些情况下可能是错误的)将数据库强制运行N次(每行一次)。有时,该功能很昂贵。一些数据库支持功能索引。但是您无法针对每个可能的输入为每个可能的函数建立索引。可以吗
上述问题的常见解决方案是从函数中提取逻辑并将其合并到查询中。现在,您已经破坏了封装和重复的逻辑。
我看到的另一个问题是在循环中调用存储过程,因为没有办法连接或相交存储的proc结果集。
declare some_cursor
while some_cursor has rows
exec some_other_proc
end
如果您从嵌套proc中提取代码,那么您将再次去中心化。因此,您不得不在封装和性能之间进行选择。
总的来说,我发现数据库不擅长:
- 计算方式
- 迭代(它们针对设置操作进行了优化)
- 负载均衡
- 解析中
数据库擅长:
- 锁定和解锁
- 维护数据及其关系
- 确保诚信
通过执行昂贵的操作(例如循环和字符串解析)并将其保留在您的应用层中,您可以水平扩展应用程序以获得更好的性能。在负载均衡器后面添加多个应用服务器通常比设置数据库复制便宜得多。
但是,您是对的,它使您的业务逻辑与应用程序的编程语言脱钩,但是我不明白为什么这是一个优势。如果您有Java应用程序,则您有Java应用程序。将一堆Java代码转换为存储过程不会改变您拥有Java应用程序的事实。
我的首选是使数据库代码专注于持久性。如何创建新的小部件?您必须插入3个表中并且它们必须处于事务中。那属于存储过程。
定义对窗口小部件可以执行的操作以及查找窗口小部件的业务规则属于您的应用程序。