数据库触发一个坏主意吗?
以我的经验,它们是邪恶的,因为它们可能导致令人惊讶的副作用,并且难以调试(尤其是当一个触发器触发另一个触发器时)。通常,开发人员甚至根本不考虑是否存在触发器。
另一方面,如果您有每次FOO
在数据库中创建新逻辑时都必须发生的逻辑,则放置它的最简单方法是在FOO表上插入触发器。
我们唯一使用触发器的时间是用于设置设置等非常简单的事情ModifiedDate
。
数据库触发一个坏主意吗?
以我的经验,它们是邪恶的,因为它们可能导致令人惊讶的副作用,并且难以调试(尤其是当一个触发器触发另一个触发器时)。通常,开发人员甚至根本不考虑是否存在触发器。
另一方面,如果您有每次FOO
在数据库中创建新逻辑时都必须发生的逻辑,则放置它的最简单方法是在FOO表上插入触发器。
我们唯一使用触发器的时间是用于设置设置等非常简单的事情ModifiedDate
。
Answers:
触发器的主要问题是
这只是意味着需要在适当的情况下谨慎使用它们。根据我的经验,这仅限于关系完整性问题(有时粒度要比声明性要好);通常不用于商业或交易目的。YMMV。
不,实际上这是个好主意。如果您的特定触发器存在问题,那么您就没有正确地执行它们,但这通常意味着您的实现存在问题,而不是触发器本身的概念:-)。
我们使用触发器的原因很多,因为它将特定于DBMS的活动置于其所属数据库的控制之下。DBMS的用户不必担心这种事情。数据的完整性在于数据库本身,而不是数据库的应用程序或用户。在数据库中没有约束,触发器和其他功能的情况下,它留给了应用程序来执行规则,并且只需要一名流氓或越野车应用程序/用户即可破坏数据。
例如,没有触发器,就不会存在诸如自动生成的列之类的奇妙事物,并且在选择它们时必须在每一行上处理一个函数。这很可能会破坏DBMS的性能,在插入/更新时创建自动生成的列会更好,因为这是唯一的更改时间。
同样,缺少触发器将阻止在DBMS强制执行数据规则,例如预触发以确保列具有特定格式。请注意,这不同于数据完整性规则,后者通常只是外键查找。
工具从不邪恶。这些工具的应用可能是邪恶的。
我同意。触发器的问题是人,而不是触发器。尽管需要更多的关注,需要更多的考虑,并增加了编码人员正确检查事情的责任,但我们不会丢弃索引来简化我们的生活。(不良索引可能与不良触发器一样糟糕)
触发器的重要性(在我看来)是...-
任何系统都应始终处于有效状态
-强制执行此有效状态的代码应集中化(并非在每个SP中都编写)
从维护的角度来看,触发器对于有竞争力的编码员和初级或业余爱好者而言非常有用。但是,这些人需要学习和以某种方式成长。
我想这取决于您的工作环境。您是否有可靠的人,他们学得很好并且可以被信奉为有条理的人?如果不是,您似乎有两个选择:
-接受必须失去功能才能弥补的
-接受您需要不同的人员或更好的培训和管理
它们听起来很刺耳,我想是的。但这是我的基本真理...
我认为触发器不仅有害,而且对于良好的数据库设计是必要的。应用程序程序员认为数据库仅受其应用程序影响。他们通常是错误的。如果无论数据变化来自何处都要保持数据完整性,就必须要有触发器,并且避免使用触发器是愚蠢的,因为某些程序员出于种族中心思想,以至于认为除珍贵的应用程序以外的其他事物可能会影响事物。如果您是一位有能力的数据库开发人员,则不难设计,测试或对触发器进行故障排除。如果您(像我一样)看到触发器,也很难确定触发器是否导致意外结果。如果我收到一条错误消息,说我未在sp中引用的表存在FK错误,我什至不考虑触发器是导致问题的原因,因此任何有能力的数据库开发人员也应如此。仅在应用程序中放置业务规则是我发现不良数据的第一原因,因为其他人不知道规则甚至存在并在其流程中违反它。以数据为中心的规则属于数据库,触发器是执行更复杂规则的关键。
some programmers are too ethnocentric to consider that something other than their prized application may be affecting things
通常,是的。
触发器的困难在于它确实会“藏在背后”。维护该应用程序的开发人员很容易无法意识到它的存在,并进行更改以至于无所适从。
它创建了一层复杂性,仅增加了维护工作。
通常可以使存储过程/例程执行相同的操作,而不是使用触发器,但是可以以一种清晰且可维护的方式进行操作-调用存储例程意味着开发人员可以查看其源代码并确切了解正在发生的事情。
触发器有其用途-记录/审核和维护“最后修改”日期是在先前的答复中提到的两个很好的用途。
但是,良好设计的核心原则之一是业务规则/业务逻辑/无论您想称呼什么,都应该集中在一个地方。将某些逻辑(通过触发器或存储的proc)放入数据库中,而将某些逻辑放入应用程序中,则违反了该原理。在两个地方重复逻辑甚至更糟,因为它们总是会彼此不同步。
已经提到了“最不惊奇的原理”问题。
正确使用触发器是不错的工具。特别适用于审核变更,填充汇总表等。
现在,如果您以一个触发其他触发的触发而陷入“触发地狱”,那么它们可能是“邪恶的”。我曾经在COTS产品上工作过,在那里他们有了所谓的“柔性触发器”。这些触发器存储在表中,因为每次执行时都会编译动态sql字符串。编译的触发器将进行查找,并查看该表是否有任何要运行的flex触发器,然后编译并运行“ flex”触发器。从理论上讲,这听起来像是一个很酷的主意,因为该产品易于定制,但实际上,由于必须进行所有编译,因此数据库几乎爆炸了。
是的,如果您以正确的眼光看待他们,那很棒。如果这很简单,例如审核,汇总,自动排序等,则没有问题。只需记住表的增长率以及触发器将如何影响性能。
概括而言,触发器有两个用例1
1)使事物“自动”发生。在这种情况下,触发器会产生副作用,它们会以给定的(原始)操作员插入,更新或删除操作(执行触发器并触发)的方式来改变数据。
这里的普遍共识是触发器确实是有害的。因为它们更改了INSERT,UPDATE或DELETE语句的众所周知的语义。更改这三个基元SQL运算符的语义将使其他开发人员感到痛苦,这些开发人员将来需要在使用SQL基元对它们进行操作时不再以预期的方式处理数据库表。
2)为了执行数据完整性规则,除了可以声明式处理的规则外(使用CHECK,PRIMARY KEY,UNIQUE KEY和FOREIGN KEY)。在此用例中,所有触发器都使用QUERY(SELECT)数据来验证是否允许由INSERT / UPDATE / DELETE进行的更改。就像声明性约束对我们所做的一样。仅在这种情况下,我们(开发人员)才对执法进行了编程。
在后一种用例中使用触发器不会造成危害。
不邪恶。他们实际上简化了诸如
1,记录/审核记录甚至数据库模式的更改
您可以在ALTER TABLE上有一个触发器,以回滚生产环境中的更改。这样可以防止意外修改表。
2.在多个数据库中强制执行引用完整性(主/外键关系等)
ALTER TABLE
。
说它们是邪恶的是夸大其词,但它们可能导致网状化。当一个触发器的触发导致其他触发器触发时,它变得非常复杂。假设它们很麻烦:http : //www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html
由于多并发问题,使用触发器在Oracle中进行业务逻辑比看起来要困难。在其他会话提交之前,您不会在其他会话中看到更改。
他们绝对不是邪恶的。我发现在数据库模式重构,重命名一列或将一列拆分为两列(反之亦然,例如名称/姓氏)并协助过渡的过程中,触发器很珍贵。
它们对于审核也非常有用。