4

我正在创建一个 Web 应用程序,用户可以在其中购买积分(使用真钱)并将其花在事物上。

我需要保留用户每次购买或花费积分的历史记录。

我经常需要知道用户当前的信用余额。

我通常遵循这样的原则,即两次存储相同的数据是不好的做法,即因为我有信用余额所有增加和减少的历史,我不应该将余额本身存储为单独的字段。

然而,每次用户打开一个新页面(这将显示他们当前的余额)时计算这个余额似乎有点过头了。另一方面,将它存储在数据库或网络服务器的内存中似乎是错误的,只是为了防止系统每次都必须解决它。

有没有人有这方面的经验和/或知道在这种情况下推荐的最佳做法是什么?

4

4 回答 4

4

我从事过几个具有类似要求的项目,即时计算当前余额并没有错——这是最不容易出错的解决方案,而这种查询是大多数数据库的设计目的;除非您在一个具有 Facebook 级别流量的网站上工作,否则类似的东西"select sum(transactionValue) from transactions where userID = ?"应该非常快。

将余额存储在其他地方 - 实际上是复制它 - 可能会引入细微的错误和差异,“缓存”值与基础交易不同步;完成这项工作所需的工作量可能很大。

于 2013-03-21T09:25:52.697 回答
2

非规范化有它的位置。例如,一个带有论坛主题的表格也有一个列,而不是为每个主题PostCount做一个。COUNT(posts)如果您担心一致性,并且您应该担心,您可以安排定期检查(例如,对来自给定用户的每笔交易或发往给定用户的每笔交易)来测试每个用户是否Balance与他们的交易总和相匹配。

于 2013-03-21T09:25:29.580 回答
2

不要计算每个请求的贷方余额。
每个用户的信用余额是您应该维护的。

将其保存在您的数据库中。
这样您就不必担心并发性。
当用户使用您的应用程序时,使用事务来递增递减此值。
数据库确实针对重复选择进行了优化,因此再次让您的数据库来处理它。

于 2013-03-21T09:26:31.720 回答
0

计算余额需要时间吗?如果没有,只需使用 SQL 实时计算。

但是当您的事务日志变得越来越大(数百万行)时,我预见到将来会出现问题。当从事务日志中选择查询需要时间时,就该缓存和预先计算余额并将其存储在您的数据库中了。

于 2013-03-21T09:27:24.730 回答