当前位置:  开发笔记 > 后端 > 正文

数据库是否会引发恶

如何解决《数据库是否会引发恶》经验,为你挑选了12个好方法。

数据库触发器是个坏主意吗?

根据我的经验,它们是邪恶的,因为它们可能导致令人惊讶的副作用,并且难以调试(特别是当一个触发器触发另一个触发器时).通常开发人员甚至不会考虑是否存在触发因素.

另一方面,似乎你必须FOO在数据库中创建一个新的逻辑,然后在数据库中创建一个新的最简单的地方是FOO表上的插入触发器.

我们唯一一次使用触发器就是设置简单的东西ModifiedDate.



1> dkretz..:

触发器的主要问题是:a)它们完全是全局的 - 无论表活动的上下文如何,它们都适用; 和b)他们是隐秘的; 很容易忘记他们在那里,直到他们以无意的(并且非常神秘的)后果伤害你.

这意味着他们需要在适当的情况下小心使用; 根据我的经验,这仅限于关系完整性问题(有时候粒度比你声明性的更细); 通常不用于商业或交易目的.因人而异.


在某些情况下,这有两个优点.
"隐身"是一个很好的词,是的 - 好吧.这正是我倾向于回避他们的原因:他们经常被遗忘或被忽视.根据我的个人经验,重访触发器往往伴随着我自己的额头.
全球化是他们为数据完整性和审计等事项做好和必要的原因.这不是一个减号,它是一个加号.
所以@RobertŠevčík-Robajz,你是说你认识的所有开发人员都不称职?
@HGLEM,同意应该有专家来制定触发器.现实生活场景 - 没有.真实场景 - 尝试识别与遗忘触发器相关的错误所花费的时间.现实生活场景 - 触发逻辑被拼命推送到应用程序逻辑中,可以轻松地进行重构和单元测试.我处理的现实生活让我说"远离触发器"......这不是触发器的错,因为它不是窗户被打破的错误.
您可以将上下文构建到触发器中.一个简单的if语句可以实现很多.
在我看来,触发器是一种地狱的方式,凌乱,而不是我遇到的单一开发人员知道如何正确处理它们.如果您认为需要触发器,请再想一想!也就是说,明智地使用触发器可以帮助您避免大量编码.我很惊讶没有人注意到视图上的"而不是"触发器.视图触发器可以帮助大量导入到SQL感知工具,并提供简单集成的方法.

2> paxdiablo..:

不,他们实际上是个好主意.如果您的特定触发器出现问题,那么您没有正确执行它们,但这通常意味着您的实现存在问题,而不是触发器本身的概念:-).

我们使用触发器很多,因为它将DBMS特定的活动置于它所属的数据库的控制之下.DBMS的用户不应该担心这类东西.数据的完整性取决于数据库本身,而不是使用它的应用程序或用户.如果数据库中没有约束和触发器以及其他功能,则由应用程序执行规则,并且只需要一个流氓或错误的应用程序/用户来销毁数据.

例如,在没有触发器的情况下,自动生成的列等奇妙的东西将不存在,并且您在选择它们时必须在每一行上处理一个函数.这可能会破坏DBMS性能,在插入/更新时创建自动生成的列要好得多,因为这是唯一一次更改.

此外,缺少触发器会阻止在DBMS上强制执行数据规则,例如预触发,以确保列具有特定格式.请注意,这与数据完整性规则不同,后者通常只是外键查找.


不一定,触发器可能仅在插入或更新行时运行.基于函数的索引将针对每个选择运行.根据使用模式,可能比另一种更好.但两者都不总是比另一个更好.
"选择它们时在每一行处理一个函数".为此目的,最好使用基于函数的索引而不是触发器.

3> Andy Webb..:

工具永远不是邪恶的.这些工具的应用可能是邪恶的.


@vbullinger枪不是邪恶的,但它们的触发器是;)
阅读评论后,我从未如此矛盾.一方面,我是第二个修正案,并且认为枪支本身并不是邪恶的:它是使用它们的人.另一方面,我认为触发器是邪恶的...我认为我有一个存在主义的崩溃......
:D概括很危险(递归)。您有没有被审讯官用来“触发”认罪的酷刑“工具”?+1仍然是透视图。

4> MatBailie..:

我同意.触发器的问题是人,而不是触发器.虽然更多的是要考虑,更多地考虑并增加编码人员正确检查事物的责任,但我们不会丢弃索引以使我们的生活更简单.(错误的索引可能和坏的触发器一样糟糕)

触发器(在我看来)的重要性在于......
- 任何系统都应该始终处于有效状态
- 强制执行此有效状态的代码应该是集中的(不是每个SP都写入)

从维护的角度来看,触发器对于竞争对手的编码器非常有用,对于更多初级/业余的编码器来说也是如此.然而,这些人需要以某种方式学习和成长.

我想这取决于你的工作环境.你有可靠的人,他们学得很好,可以信任有条不紊吗?如果不是你,你似乎有两个选择:
- 接受你必须失去功能来补偿
- 接受你需要不同的人或更好的培训和管理

它们听起来很刺耳,我想它们都是.但这是基本的事实,在我看来......


>>>触发器的问题是人.是的,如果只有人可以在装配中编码,使用蹩脚的GUI工作,正确猜测是否推或拉一个设计糟糕的门...任何"功能"的人反复错误是"邪恶的".

5> HLGEM..:

我认为触发器不仅不是邪恶的,而且是良好的数据库设计所必需的.应用程序员认为数据库只受其应用程序的影响.他们经常是错的.如果要保持数据完整性,无论数据发生在何处,触发器都是必需的,并且避免它们是愚蠢的,因为一些程序员过于种族中心,不能认为除了他们珍贵的应用程序之外的其他东西可能会影响事物.如果您是一位称职的数据库开发人员,那么设计或测试或排除触发器故障并不困难.如果触发器发生意外结果(如果它对我来说那样),那么也很难确定触发器是否会导致意外结果.如果我得到一个错误,说我在sp中没有引用的表有一个FK错误,我知道甚至没有想到触发器导致问题,所以任何有能力的数据库开发人员也应如此.仅将业务规则放在应用程序中是我发现坏数据的首要原因,因为其他人不知道规则甚至存在并且在其进程中违反规则.以数据为中心的规则属于数据库,触发器是实施更复杂的规则的关键.



6> MarkR..:

大多数情况下,是的.

触发器的难点在于它"背后"; 维护应用程序的开发人员可能很容易意识到它并没有意识到并且进行了更改,这些更改会使事情变得棘手,甚

它创造了一层复杂性,只增加了维护工作.

通常可以使用存储过程/例程来执行相同的操作,而不是使用触发器,但是以清晰且可维护的方式 - 调用存储的例程意味着开发人员可以查看其源代码并查看确切的发生情况.


这是一个触发器的优点,而不是disadvatage!无法保证在每次更改数据时都调用存储过程.除了GUI之外,还有很多方法可以更改数据.
如果应始终一起创建/销毁记录,请创建一个确保它们的检查约束.这样,违反规则的人会得到错误,而不是隐藏的行为,在没有他们知情或同意的情况下,这些行为会神奇地使事情变得正确.

7> Robin Day..:

触发器非常强大且有用,在任何情况下触发器都是解决问题的最佳方案.

它们也是一个非常好的"黑客"工具.通常情况下,您无法立即控制代码和数据库.如果您必须等待2个月才能获得代码的下一个主要版本,但是您可以立即将修补程序应用于数据库,那么您可以在表上设置触发器以执行一些其他功能.然后,当代码发布可能时,您可以根据需要将此触发器替换为相同功能的编码版本.

在一天结束时,如果你不知道它在做什么,一切都是"邪恶的".决定触发器是因为有开发人员不了解它们与认为汽车是邪恶的是相同的,因为有些人无法开车......



8> Dave Sherohm..:

触发器有其用途 - 记录/审计和维护"上次修改"日期是两个非常好的用途,在之前的回复中已经提到过.

然而,良好设计的核心原则之一是业务规则/业务逻辑/无论您想要什么,都应该集中在一个地方.将一些逻辑放入数据库(通过触发器或存储过程)和应用程序中的一些逻辑违反了该原则.在两个地方复制逻辑甚至更糟,因为它们总是彼此不同步.

还有一个已经提到的"最少惊喜原则"问题.


这是正确的它应该在一个地方,数据库.影响数据完整性的逻辑必须始终存在于数据库中,并且永远不会出现在影响数据库中的数据时可能会或可能不会被调用的应用程序中.
从未在仅通过Object层将数据插入数据库的业务应用程序上工作,我不想在其中工作.将百万记录导入或所有价格的更新通过旨在一次只处理一个记录的过程来愚蠢是愚蠢的.对象层是强制数据完整性的错误位置,这就是为什么这么多数据库存在完整性问题的原因.

9> tmeisenh..:

如果使用得当,触发器是一个很好的工具.特别适用于审计更改,填充汇总表等内容.

现在他们可能是"邪恶的",如果你最终陷入"触发地狱",一个触发器开启其他触发器.我曾经在COTS产品上工作过他们所谓的"弹性触发器".这些触发器存储在一个表中,因为每次执行时都会编译动态sql stings .编译的触发器会查找并查看该表是否有任何flex触发器运行,然后编译并运行"flex"触发器.从理论上讲,这听起来像是一个非常酷的想法,因为产品很容易定制,但实际情况是数据库因为必须做的所有编译而爆炸了很多...

所以,是的,如果你保持你正在做的事情,他们是伟大的.如果它像审计,总结,自动排序等非常简单,没有概率.请记住表的增长率以及触发器将如何影响性能.



10> Toon Koppela..:

在较高级别,触发器1有两个用例

1)使"自动化"的东西发生.在这种情况下,触发器会产生副作用,它们会以预期的方式更改数据,前提是(原始)操作符插入,更新或删除已执行并导致触发器触发.

这里的普遍共识是触发器确实是有害的.因为它们改变了INSERT,UPDATE或DELETE语句的众所周知的语义.更改这三个原始SQL运算符的语义会让其他开发人员感到困惑,这些开发人员将来需要处理数据库表,这些表在使用SQL原语操作时不再以预期的方式运行.

2)执行数据完整性规则,而不是我们可以声明性地处理的规则(使用CHECK,PRIMARY KEY,UNIQUE KEY和FOREIGN KEY).在此用例中,所有触发器都是QUERY(SELECT)数据,以验证是否允许INSERT/UPDATE/DELETE进行更改.就像声明性约束对我们来说一样.只有在这种情况下,我们(开发人员)已经对执法进行了编程.

对后一种用例使用触发器是无害的.

我在博客上写道:http://harmfultriggers.blogspot.com


同意.但是使用其他方法会更容易吗?

11> DanSingerman..:

我知道认为触发器的开发人员应该始终使用它是实现所需功能的最直接方式,而开发人员永远不会.这几乎就像两个阵营之间的教条.

但是我个人完全同意MarkR - 你可以(几乎)总是编写功能相当于触发器的代码,这些代码将更加明显,因此更易于维护.



12> Chris..:

不是邪恶的.他们实际上简化了类似的事

1.记录/审核记录甚至数据库模式的更改

您可以在ALTER TABLE上使用触发器来回滚生产环境中的更改.这应该可以防止任何意外的表修改.


2.跨多个数据库实现参照完整性(主/外键关系等)

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有