当涉及在事务数据库中对数据进行非规范化以提高性能时,至少有三种不同的方法:
通过存储过程推送更新,存储过程更新规范化的事务数据和非规范化的报告/分析数据;
在更新辅助表的事务表上实现触发器;这几乎总是维护历史时所采取的路线;
将处理推迟到夜间批处理过程,可能将ETL插入数据集市/仓库。
我们假设为了这个问题的目的,选项#3是不可行的,因为域要求非规范化数据始终与规范化数据一致。我经常处理的分层聚合就是其中的一个例子。
我已经使用了前两种方法,最近我一直倾向于基于触发器的方法,但我想知道是否有任何“陷阱”我还没有发现,并且认为值得提出这个问题,所以在将来做出长期决策时我会记住一些想法。
那么根据您的经验,这两种工具的优缺点是什么,以保持实时非规范化数据的特定目的?在什么情况下你会选择一个而不是另一个,为什么?
(P.S。请不要回答“触发器过于复杂”或“所有更新应始终通过存储过程” - 使其适合问题的上下文。)
答案 0 :(得分:8)
如果表上有多个更新路径,则触发器非常有用。
我们使用存储过程并至少有4条路径(添加,更新,停用,复制)
使用我们刚刚在触发器中插入/更新的数据更容易,无论我们采取什么操作或我们影响了多少行。
存储过程仅适用于单个更新路径我觉得:除非您想重复代码...
现在,触发器中的TRY / CATCH意味着正确,可预测的错误处理:SQL Server 2000及更早版本上的触发器导致错误/回滚的批量中止,这是不理想的(至少可以说!)。所以,无论如何,触发器现在更可靠。
答案 1 :(得分:7)
触发器是自动副作用,当您想要执行某些操作时几乎肯定会让您失望,但由于触发器的副作用而无法触及。主要是让您的系统参与在某些XA交易中与其他外部系统。触发器使这个不可能。它也是副作用逻辑,只能通过再次执行触发激活器来激活。如果你想在仓库中重新创建数据,你不能只运行一些程序并重新创建它,你必须执行所有会触发触发器的活动,这是一场噩梦。 INSERTS,UPDATES和DELETES应该是幂等的和正交的。触发器不必要地使工作流程复杂化,即使您认为它们正在简化它们,也不是。
答案 2 :(得分:0)
这取决于您的业务要求以及数据库的使用方式。例如,假设有许多应用程序和许多影响表的导入(我们有数百种可能影响我们表的东西)。假设有时需要编写从SSMS运行的查询(甚至是prod),以执行更新所有价格10%的操作。如果你做这些类型的事情然后存储过程是不切实际的,你将永远不会有一切可能的方式来影响所涵盖的数据库。
如果数据更改对于数据完整性或许多应用程序或进程(导入,SQL Server作业等)可能会影响数据,那么它属于触发器。
如果有时只需要更改数据,或者您只能从一个应用程序完全控制数据的更改方式,那么存储过程就可以了。