用户账户余额应该存储在数据库中还是动态计算?

15

用户的账户余额应该存储在数据库中还是动态计算?

为了得到准确的结果,动态计算似乎更合理,但当用户数量增多且数据库变得非常大时,这可能会成为问题。

交易

  • Id (主键)
  • AccountId(账户id)
  • Type(类型)
  • DateTime(时间)
  • Amount(金额)
  • 等等。。。

账户余额

  • TransactionId(主键/外键)
  • BalanceAmount(余额金额)

1
如何动态计算并将其存储在数据库中?这意味着用户可以随时查看他的余额。 - Mick Walker
保留更改日志,并为实际数据保留一个“软”记录。软记录只是一个最新的带有大部分平衡数据的字段。在单个事务中更新所有字段,就可以了。对于简单的游戏,我只会保留一个“金额”字段。 - CodingBarfield
5个回答

14
为了保持准确的审计,您应记录影响用户账户余额的每笔交易。这意味着您可以动态计算余额,但出于性能原因,我建议也将余额存储下来。为了确保余额正确,我建议每天运行一个作业来从头开始重新计算余额。

2
你需要问自己几个问题: 1)谁将拥有这个计算? 2)谁需要这个结果?
如果计算的所有者是唯一需要它的人,或者任何其他需要它的人都会从所有者那里得到它,那么就没有必要存储该计算。
然而,在大多数长时间运行的应用程序中,计算结果可能最终需要在其他地方使用。例如,像SQLReportingServices这样的报告应用程序将需要计算结果,因此,如果计算的所有者是Web应用程序,则存在问题。报告服务(仅与数据库通信)如何获取结果?
在这种情况下的解决方案 - 要么存储计算结果,要么使数据库成为计算的所有者,并有一个SQL函数返回结果。
就我个人而言,我倾向于采用非纯粹主义方法 - 将计算结果存储在数据库中。空间便宜,读取速度比读取+函数调用快。

2

我认为这是一个好问题。每次计算显然很容易做到,但可能会导致很多不必要的计算,并产生性能损失。

但是,在其他表中存储当前余额可能会导致数据并发性方面的问题,其中用于构建聚合的数据与聚合本身的数据不同步。

也许一种折衷方法是在交易表上设置 SQL 触发器,以在用户插入或更新时更新聚合值。


1

当前余额已经可用!这是账户上最后一笔交易的余额:

select top 1 [Balance]
from dbo.Trans
where [AccountID] = @AccountID
order by [TranID] desc

每次交易都必须计算和存储余额,否则系统无法扩展... 此外,如果您不存储余额,就没有核对和平衡(如余额必须等于先前余额加上新的信用减去新的借记)


0
  1. 如果您的应用程序在需要余额时没有从数据库检索数据进行余额计算,我建议您应该计算余额或将其存储在数据库中。

  2. 如果您需要经常更新余额,并且它是基于多个表动态更改的,则应该使用表视图而不是触发器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接