触发器或计算字段

时间:2013-05-24 14:17:25

标签: sql firebird

我想知道当我想在同一个表中显示计算某些字段的结果时,我应该将其作为计算字段还是使用“插入或更新前”触发器?

注意:我发现了类似的问题,但它是针对SQL Server的,我需要知道何时将结果显示在网格中,其中有许多记录可见,如果计算字段会影响这种情况下的性能。

我现在在计算字段中使用的计算示例:

field_1 * (
  iif(field_2 is null,0,1)
 +iif(field_3 is null,0,1)
 +iif(field_4 is null,0,1)
 +iif(field_5 is null,0,1))

2 个答案:

答案 0 :(得分:3)

触发器仅在您将信息存储在表格中时才有效,因为它们仅在实际发生INSERTUPDATEDELETE时被触发。它们对SELECT语句没有影响。因此,实际问题变为“我应该在SELECT语句中计算列值,还是添加一列来存储它们?”。

无需存储可在SELECT中轻松计算的值,并且在执行此处所包含的简单计算时,很少会对性能产生影响。

是否应该存储它取决于许多因素,例如数据更改的频率,以及结果集对典型查询的大小。返回的行越多,计算的影响就越大,并且在某些时候,计算过程的成本会比添加列的增加的存储要求更高。但是,如果您可以限制查询返回的行数,则计算成本可以忽略不计,因为在不需要时为每行维护额外的数据列的开销可能会更高,因为插入的每一行或更新后,即使没有访问该数据,也会执行触发器。

但是,如果典型查询返回的行数非常多或者计算非常复杂,则计算可能会变得非常昂贵,以至于最好将数据存储在可以快速轻松检索的实际列中。但是,如果频繁插入或更新数据,则触发器的执行会减慢这些操作的速度,如果它们比大SELECT个查询更频繁地发生,则可能不值得权衡。

至少有一个缺点(我没有提及,但你在下面的评论中提到)实际将计算结果存储在一列中。如果你的计算(公式)逻辑改变了,你必须:

  • 禁用触发器
  • 根据新计算
  • 更新所有具有新值的行
  • 编辑触发器以使用新计算
  • 重新启用触发器

在您的查询本身进行计算后,您只需更改查询的SQL即可。

所以我的回答是

  • 除非您有明确的理由不这样做,否则通常更好地计算列值,
  • “这样做的明确理由”意味着您可以证明与计算有关的实际性能影响,或者您需要SELECT非常大量的行并且计算相当紧密。

答案 1 :(得分:1)

性能应该没问题,除非您的计算字段成为WHERE子句的一部分时使用更大的表。另一方面,即使由其他字段计算,如果您的要求允许因某种原因覆盖计算值。那么你也需要一个真实的物理场。