我试图找出我是否应该使用关键业务的逻辑中的一个触发或约束我的数据库。
迄今为止我已经加入的逻辑在触发器,因为它给了我控制在接下来会发生什么和意味着我可以提供自定义用户的邮件而不是一个错误,可能会混淆用户。

是否有任何显着业绩收益,在使用限制在触发和什么是最佳做法,确定其使用。

有帮助吗?

解决方案

约束的手下!

  • 与约束的指定关系的原则,即事实关于你的数据。你将永远不需要改变你的约束,除非某些事实的变化(即新的要求)。

  • 与会触发你指定如何处理数据(插入、更新等等)。这是一个"非关系"的做事方式。

为更好地解释自己与一个比喻:适当的方式编写一个SQL查询是指定"你想要的"而不是"如何得到它的"–我们的关系型数据库找出最佳的方式来为你做它。这同样适用在这里:如果您使用的触发你必须记住各种这样的事情以执行,联,等等。让SQL为你做的约束,如果可能的。

这并不是说,触发器,没有使用。他们做的:有时候你不能使用限制指定一些事实有关你的数据。这是极为罕见,虽然。如果它发生的你 很多, 然后大概有一些问题的架构。

其他提示

最佳实践:如果您可以使用约束来执行此操作,请使用约束。

触发器并没有那么糟糕(如果正确使用的话),尽管我总是会尽可能地使用约束。 在现代RDMS中,触发器的性能开销与约束相当(当然,这并不意味着某人无法在触发器中放置可怕的代码!)。

偶尔有必要使用触发器来强制执行“复杂”约束,例如想要强制执行一个并且只填充一个表的两个外键字段中的一个(我在几个域中看到过这种情况)型号)。

关于业务逻辑应该驻留在应用程序而不是数据库中的争论在某种程度上取决于环境;如果您有许多应用程序访问数据库,则约束和触发器都可以作为数据正确的最终保护。

触发器可能会成为性能问题。大约在同一时间,它们也成为维护的噩梦。你无法弄清楚正在发生的事情(奖励!)应用程序与“虚假”的行为不一致数据问题。 [真的,它们会触发问题。]

没有最终用户直接接触SQL。他们使用应用程序。应用程序包含的业务逻辑比触发器更智能,更易于维护。将应用程序逻辑放在应用程序中。将数据放入数据库。

除非您和您的“用户”在不共享共同语言,您可以向他们解释约束违规。替代方案 - 不解释 - 将一个简单的数据库变成一个问题,因为它将数据和应用程序代码混合成一个不可维护的泥潭。

“我如何绝对保证每个人都正确使用数据模型?”

两种(半)技术。

  1. 确保模型正确:它与实际问题域匹配。没有黑客或变通方法或快捷方式,只能通过复杂的挥手解释,存储过程和触发器进行整理。

  2. 帮助定义应用程序的业务模型层。每个人共享和重用的应用程序代码层。

    一个。此外,请确保模型层满足人们的需求。如果模型层具有正确的方法和集合,那么绕过它以获得对底层数据的直接访问的动机就会减少。一般来说,如果模型是正确的,这不是一个深刻的问题。

  3. 触发器是一种等待发生的火车残骸。约束不是。

除了使用约束的其他原因之外,Oracle优化器可以使用约束来实现它的优势。

例如,如果你有一个约束说(Amount> = 0)然后用 WHERE(Amount = -5)查询Oracle立即知道那里没有匹配的行。

约束和触发器适用于两种不同的事物。约束用于约束数据的域(有效输入)。例如,SSN将存储为char(9),但约束为[0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [ 0-9] [0-9] [0-9](全数字)。

触发器是一种在数据库中实施业务逻辑的方法。再次采用SSN,或许每当SSN发生变化时都需要维护审计线索 - 这将通过触发器来完成,

通常,现代RDBMS中的数据完整性问题可以通过约束的某些变体来处理。但是,您有时会遇到这样的情况:不正确的规范化(或更改的要求,导致现在不正确的规范化)会阻止约束。在这种情况下,触发器可能能够强制执行您的约束 - 但它对RDBMS是不透明的,这意味着它不能用于优化。它也是“隐藏的”逻辑,可能是一个维护问题。决定是否重构模式或使用触发器是一个判断调用。

一般来说,我更喜欢约束,我的代码会捕获sql server错误并向用户呈现更友好的内容。

@onedaywhen

您可以在SQL Server中将查询作为约束,只需将其置于标量函数中即可: http://www.eggheadcafe.com/software/aspnet/30056435/check-contraints-and-tsql.aspx

@Mark Brackett:“约束用于约束域...触发器是一种强制执行业务逻辑的方式”:在SQL Server中并不是那么简单,因为它的约束功能是有限的,例如:尚未完整的SQL-92。在时态数据库表中采用有序“主键”的经典示例:理想情况下,我使用带有子查询的CHECK约束来防止同一实体的重叠周期,但SQL Server不能这样做,所以我必须使用触发。 SQL Server中缺少的是SQL-92延迟检查约束的能力,但是它们(实际上)在每个SQL语句之后都被检查,因此可能需要一个触发器来解决SQL Server的限制。

如果可能的话,使用约束。他们往往更快。触发器应该用于约束无法处理的复杂逻辑。触发器写入也很棘手,如果你发现你必须编写一个触发器,请确保使用基于set的语句,因为triigers对整个插入操作,更新或删除(是的,有时会有多个记录受到影响,计划在那!),而不是一次只有一个记录。如果可以避免,请不要在触发器中使用光标。

是否将逻辑放在应用程序中而不是触发器或约束。不要那样做!!!是的,应用程序在发送数据之前应该进行检查,但数据完整性和业务逻辑必须处于数据库级别,否则当多个应用程序挂钩时,当全局插入完成在应用程序之外时,您的数据将变得混乱。完整性是数据库的关键,必须在数据库级别强制执行。

@Meff:使用函数的方法存在潜在问题,因为简单地说,SQL Server CHECK约束是以单行作为工作单元设计的,并且在处理结果集时存在缺陷。有关详细信息,请参阅:[ http://blogs.conchango.com/davidportas/archive/2007/02/19/Trouble-with-CHECK-Constraints.aspx] [1]

[1]:David Portas的博客:CHECK约束的麻烦。

与Skliwz相同。 只是为了让您知道规范使用触发器是审计表。如果许多过程更新/插入/删除您要审核的表(谁修改了什么以及何时更改),则触发器是最简单的方法。一种方法是简单地在表中添加一个标志(具有一些unicity约束的活动/非活动)并在审计表中插入一些内容。

如果您希望表不保存历史数据,另一种方法是复制审计表中的前一行......

许多人有很多方法可以做到这一点。但有一件事是肯定的,你必须为这个表中的每个更新/插入/删除执行插入

为了避免在不同地方写入插入内容,您可以使用触发器。

我同意所有人的约束。尽可能多地使用它们。

过度使用触发器的趋势,尤其是新开发人员。我已经看到触发器触发另一个触发器的情况,该触发器触发另一个重复第一个触发器的触发器,创建一个连接服务器的级联触发器。这是触发器的非最佳用户; o)

话虽如此,触发器有它们的位置,应该在适当时使用。它们特别适合跟踪数据的变化(正如Mark Brackett所提到的)。您需要回答“将业务逻辑放在哪里最有意义”的问题?大多数时候我认为它属于代码,但你必须保持开放的心态。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top