数据库触发器与 Rails ActiveRecord 回调的优缺点?

Posted

技术标签:

【中文标题】数据库触发器与 Rails ActiveRecord 回调的优缺点?【英文标题】:Pros and cons of database triggers vs Rails ActiveRecord callbacks? 【发布时间】:2011-11-12 19:38:02 【问题描述】:

我正在使用 Ruby on Rails 和 PostgreSQL 编写程序。系统会生成大量报告,这些报告经常被用户更新和访问。我在是否应该使用 Postgres 触发器来创建报告表(如 Oracle 物化视图)或 Rails 内置的 ActiveRecord 回调之间犹豫不决。有没有人对此有任何想法或经验?

【问题讨论】:

【参考方案1】:

回调在以下情况下很有用:

在 Rails 模型中结合所有业务逻辑,便于维护。 利用现有的 Rails 模型代码 易于调试 Ruby 代码比 sql“可维护性”更容易编写/阅读

触发器在以下情况下很有用:

性能是一个大问题。它比回调更快。

如果您关心的是简单明了,请使用回调。如果您关心的是性能,请使用触发器。

【讨论】:

使用触发器时性能提升的原因是什么? 因为在回调中,您将连接到数据库,但是在触发器中您不需要连接到数据库,您已经在数据库层 非常重要的是,数据库触发器允许您规避一些与条件相关的并发问题。以在某些条件下更新某些列的情况为例。考虑到您没有在同一个事务中使用这两个条件(这在 Rails 中很容易做到),因此无法保证在实际更新列时您的条件仍然成立。 使用回调的一个缺点是,如果由于某种原因,您不能使用您的客户端将您的记录插入数据库,如果您忘记手动应用所需的记录,则可能会出现不一致的记录变化,我在现实生活系统中看到了很多这样的问题【参考方案2】:

我们遇到了同样的问题,由于这是一个有趣的话题,我将根据我们的选择/经验进行详细说明。

我认为这个概念比当前答案中强调的更复杂。

由于我们讨论的是报告,我假设用例是更新数据仓库表 - 而不是“通用”应用程序(这个假设/区别至关重要)。

首先,“易于调试”的想法并非[必然]正确。在我们的例子中,这样想实际上适得其反。

在足够复杂的应用程序中,某些类型的回调(数据仓库更新/数百万行代码/中等(或更多)规模的团队)根本无法维护,因为数据库将更新的地方/方式太多了, 几乎不可能调试错过的回调。

触发器不必设计为“复杂而快速”的逻辑。 具体来说,触发器也可以用作低级回调逻辑,因此简单而精简:它们只需将更新事件转发回 Rails 代码。

最后,在提到的用例中,应该像瘟疫一样避免使用 rails 回调。

一种高效且有效的设计是让 RDBMS 触发器将记录添加到队列表中,并使用 Rails 端排队系统对其进行操作。

(由于这个帖子太老了,我很好奇OP的经历是什么)

【讨论】:

以上是关于数据库触发器与 Rails ActiveRecord 回调的优缺点?的主要内容,如果未能解决你的问题,请参考以下文章

数据库触发器与 Rails ActiveRecord 回调的优缺点?

Rails 中模型的不正确复数

Rails - 调用模型的方法时在视图中获取对象的字段

如何在整个 Rails 活动记录关联链中取消特定模型的默认范围?

是否可以在数据库列中的字符串上放置最小长度,或者只能通过模型 上的验证来完成?

Rails 重置密码电子邮件未触发