试图设计一个应该从另一个表中求和的列

时间:2010-02-08 08:55:51

标签: database database-design aggregate-functions

抱歉,如果标题不是很清楚。我现在试着解释一下:

我有两个表:表A和表B.它们之间的关系是一个(对于A表)到很多(对于B表)。所以,这就像主人详细情况。 表B中有一列“Amount”,显然是十进制数,表A中有一列“TotalAmount”。 我正在努力弄清楚如何保持表A中的值是最新的。我的建议是基于表A创建一个视图,其中聚合查询计算表B中的金额。当然,使用正确的索引... 但是,我的队友建议每次我们从应用程序中更改表B中的内容时更新表A中的值。 我想知道,这里最好的解决方案是什么?可能是第三种变体?

一些澄清......我们希望这些表是我们数据库中增长最快的表。表B的增长速度远远快于表A.表B中最常见的操作是插入...而几乎没有别的。表A中最常见的操作将是选择......但不仅如此。

4 个答案:

答案 0 :(得分:1)

我看到了很多选择:

  1. 在表B上使用插入触发器,并按照朋友的建议执行更新表A.这将使表B尽可能保持最新。
  2. 预定作业每x分钟更新一次表格(x =对您的应用程序有意义的任何内容)。
  3. 更新表B时,请在应用程序逻辑中对表A进行更新。如果您在许多地方更新表B,则可能无法解决此问题。

答案 1 :(得分:1)

如果您的应用中有一个位置向表B插入新行,那么最简单的解决方案是发送UPDATE A set TotalAmount=TotalAmount + ? where ID = ?并将您刚刚用于插入的值传递给B.确保您在事务中包装两个查询(插入和更新),以便两者都发生或者都不发生。

如果这不简单,那么您的下一个选项是数据库触发器。阅读数据库的文档如何创建它们。基本上,触发器是在DB中发生某些事情时执行的一小段代码(在您的情况下,当有人在表B中插入数据时)。

该视图是另一种选择,但它可能会在您难以解决的选择过程中导致性能问题。请尝试使用“物化视图”或“计算列”(但这些可能会在插入/删除列时导致性能问题)。

答案 2 :(得分:1)

如果这个值会发生很大变化,那么最好使用视图:这绝对是更安全的实现。但更好的方法是使用触发器(如果你的数据库支持它们。)

我猜你的伙伴建议更新每个插入的值,因为他认为你会经常需要这个值,并且每次都可能导致减慢重新计算值。如果是这样的话:

  • 您的数据库应该负责缓存,因此这可能不是问题。
  • 尽管如此,您可以在以后添加该功能 - 这样您就可以确保您的应用程序正常工作,并且可以更轻松地更多调试该缓存列。

答案 3 :(得分:0)

我肯定会建议使用触发器而不是使用应用程序逻辑,因为这可以确保数据库使值保持最新,而不是依赖于所有调用者。但是,从设计的角度来看,我会谨慎地将生成的数据存储在与非生成数据相同的表中 - 我认为保持清晰的分离很重要,因此人们不要混淆他们应该在哪些数据之间保持并为他们维持什么。

但是,通常情况下,首选视图到触发器 - 这样您就不必担心维护该值了。用于确定性能是否存在问题的配置文件。在Postgres中,我相信您甚至可以在计算值上创建索引,因此数据库不必查看详细信息表。

第三种方法,定期重新计算,将比触发器慢得多,并且可能比视图慢。无论如何,它不适合你的使用是锦上添花:)。