我一直在努力寻找一种方法来正确可靠地维护订单/付款系统中的帐户余额。
目前,该过程由三个表组成。下面的示例非常简化,但可以理解。
表一包含账户 ID、名称、支付总额、订单总数、余额等。
表二包含付款、日期、帐户 ID (FK) 和金额。
表三包含订单、日期、帐户 ID (FK) 和金额。
计算余额当然很简单
SELECT SUM(payments.AMOUNT) FROM payments WHERE ID = [account]
SELECT SUM(orders.AMOUNT) FROM orders WHERE ID = [account]
Run Code Online (Sandbox Code Playgroud)
接下来是一些简单的加法/减法数学:
UPDATE accounts SET BALANCE = [balance] WHERE ID = [account]
Run Code Online (Sandbox Code Playgroud)
一切都很好 - 问题是 - 我如何保持这一点,让我们假设多年的活动和许多交易?
当前,每次进行交易时都会更新帐户表,这意味着每次都会运行上述三个语句。当然,所有三个表中的 ID 列都有一个索引,现在一切都快速而整洁,但我处理的事务少于 100,000 个,这意味着所有内容都适合 RAM,基本上我扔给数据库的所有内容都会立即执行. 随着时间的推移,这当然会改变——那么我该如何处理呢?
将帐户标记为“脏”并稍后在批处理作业中处理平衡是否更好,或者即使我到达订单和付款表无法放入 RAM 的点,我是否可以继续实时更新余额?
我是否需要在给定时间之前(例如在上次计算之前)分割订单和付款并“锁定”所有内容?(我宁愿不)。我问是因为这样我就可以做一个 SUM WHERE DATE > [last lock timestamp] 并使用 UPDATE BALANCE = [balance] + [value for last lock] 进行更新,并防止问题超出资源。
我不需要每笔交易的运行余额。当我尝试研究这个问题时,这就是我所能找到的所有结果。我只关心支付的总金额、订购的总金额和账户余额。
你问我为什么在需要余额时不即时计算?因为人们必须能够查询系统并询问“我的(假设)50.000 个帐户中哪个帐户的余额低于 0?” - 如果我们不将余额存储在每个帐户中,我们就无法轻松做到这一点。
mysql ×1