我应该创建一个普通触发器还是多个小触发器?

Should I create one common trigger or several small triggers?

什么是更好的编程实践:

编写一个通用触发器来处理多个 aspects/rules?

为每条规则编写一个触发器?

例如我有一个数据库 'Library' 有 4 tables:

期刊、客户、书籍和 Books_types。

INSERT 到 table 期刊的规则:

  1. 字段DATE_END应该是自动生成的;
  2. 应减少 Books 中的字段 COUNT;
  3. Book_types 中的字段 COUNT 应该减少。

什么是更好的选择:3 个小触发器还是 1 个普通触发器?

就我个人而言,我会用一个触发器来完成,这样维护它的人更容易看到发生了什么

这在某种程度上取决于确切的要求(一如既往),但只有一个触发器有一些优点:

  1. 根据 documentation 触发器的执行顺序未定义,我不希望在我的应用程序中出现任何类型的不确定行为。

Oracle fires multiple triggers in an unspecified, random order, if more than one trigger of the same type exists for a given statement; that is, triggers of the same type for the same statement are not guaranteed to fire in any specific order.

  1. 根据规则"keep one information in one place",我宁愿将所有逻辑也添加到一个触发器中。为了遵循 "divide and conquer" 模式,您可以在该触发器中调用多个过程或函数。

  2. 很可能一个触发器在执行时间方面更快,并且不会像三个触发器那样增加复杂性。想象一下,如果你有 300 个触发器而不是 100 个触发器......

根据您是否 运行 陷入 ORA-04091: table Journal is mutating 错误,您甚至可能不得不将您的逻辑拆分为多个触发器。检查此站点关于 avoiding mutation tables

我认为它会给出变异错误。因为小触发器可能包含一些会产生变异错误的动作。

例如- 您不能为 AFTER INSERT 事件编写更新触发器。

这里没有真正的最佳实践;这完全取决于你在做什么以及它有多复杂。

我会将字段的默认值放在 Library table 中的 BEFORE 行触发器中。所以 DATE_END 的默认值(假设我不能使用 DEFAULT SYSDATEDEFAULT CURRENT_TIMESTAMP 作为字段约束)。这样我就写了一次 table 。如果我在字段上有 NOT NULL DEFAULT NULL 限制,我认为 BEFORE 触发器是执行此操作的唯一方法。

然后我会对其他 table 中的字段使用 AFTER 语句或 AFTER 行触发器,主要是因为可能有外键或其他类似要求需要我当前插入的数据实际在 table 中(就像序列生成的 ID)。这似乎在哲学上更正确,但我对 Oracle 约定的熟悉程度不如其他人。

最好实施规则来处理您要生成插入的内容。因为修改规则可以在futcher中长大,这会影响dml性能

我建议使用多个有针对性的触发器 - 每个操作一个。

这样一来,您无需花费任何时间在触发器本身中编写任何代码来确定您面临的是什么操作 - 从触发器是 FOR UPDATEFOR DELETE。这使得触发器代码更简单,更不容易出错,并且将来更容易维护。