1

对不起,如果标题不是很清楚。我现在将尝试解释:

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

一些澄清......我们希望这些表成为我们数据库中增长最快的表。并且表 B 的增长速度将比表 A 快得多。表 B 中最频繁的操作将是插入……而几乎没有其他操作。表 A 中最频繁的操作将是 select ... 但不仅如此。

4

4 回答 4

1

我看到了许多选项:

  1. 在表 B 上使用插入触发器并按照您朋友的建议更新表 A。这将使表 B 尽可能保持最新。
  2. 有一个计划的作业,每 x 分钟更新一次表 A(x = 对您的应用程序有意义的任何内容)。
  3. 更新表 B 时,请在应用程序逻辑中更新表 A。如果您在许多地方更新表 B,这可能无法解决。
于 2010-02-08T09:00:53.043 回答
1

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

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

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

于 2010-02-08T09:03:53.210 回答
1

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

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

  • 您的数据库应该负责缓存,因此这可能不会成为问题。
  • 但是,如果是这样,您可以在稍后阶段添加该功能 - 这样您可以确保您的应用程序以其他方式工作,并且可以轻松地调试该缓存列。
于 2010-02-08T09:10:02.393 回答
0

我肯定会推荐使用触发器而不是使用应用程序逻辑,因为这样可以确保数据库保持值是最新的,而不是依赖于所有调用者。但是,从设计的角度来看,我会警惕将生成的数据与非生成的数据存储在同一个表中——我认为保持清晰的分离很重要,这样人们就不会对应该使用哪些数据感到困惑正在维护以及将为他们维护什么。

然而,一般来说,更喜欢视图而不是触发器——这样你就不必担心维护值了。配置文件以确定性能是否是一个问题。在 Postgres 中,我相信您甚至可以在计算值上创建索引,这样数据库就不必查看详细信息表。

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

于 2010-02-08T09:15:26.230 回答