使用多个成本表计算用户的余额



我们正在构建一个SaaS产品,用户可以从各种类型的交易中产生成本,例如:

  • 拨打电话
  • 发送短信
  • 存储录音

我们已经构建了我们的系统来存储每个服务的成本,例如call_audit表如下所示:

Date       Call ID  Our Cost  User Cost Currency Duration User ID
---------- -------- --------- --------- -------- -------- -------
2018-01-02 sm_123   0.01      0.02      USD      72       us_1

sms_audit表如下所示:

Date       SMS ID   Our Cost  User Cost Currency User ID
---------- -------- --------- --------- -------- -------
2018-01-02 sm_123   0.01      0.02      USD      us_1

然后有一个包含用户付款和退款的payment_audit表:

Date       User ID  Amount Currency Type 
---------- -------- ------ -------- ----
2018-01-02 us_1     12     USD      CHARGE
2018-01-02 us_1     -2     USD      REFUND

我们还有一个带有balance列的user表,当用户产生电话,短信费用或退款时,我们会减少该列。当用户向帐户付款时,我们会将其递增(CHARGE如上所述(。

但展望未来,我认为我们需要比在代码中更新的单个余额数字更具弹性的东西。

一项改进是使用触发器而不是在代码中更新余额数字。

另一种方法是计算用户在多个表中的总成本和付款,并对批次求和。随着表格增长到许多 1000 个事务,我可以想象这成为一个缓慢的计算。

我们想到的另一种方法是有一个balance_transactions表,其中包含debitcredit并运行balance列。这当然会导致行之间的传递依赖关系,如果寻求一个很好的规范化数据库,这不是很好。这也意味着我们正在复制数据,但在现实世界中,这是一个可以接受的权衡吗?

通过使用实例化视图,可以避免重复数据。请注意,更新余额(以任何方式 - 通过应用程序、触发器、部分运行余额(已经复制了数据。因此,您应该运行一些验证过程来提醒差异。这样的验证过程应该完成所有计算,所以它们也可以填充物化视图。

但是,实际解决方案取决于您需要这些数据的频率。例如,如果您每月获取所有客户余额以开具发票,请不要复制它们。但是,如果您在每次客户操作后打印余额,例如在某种交易确认中(例如生成并通过电子邮件发送给客户的 PDF(,您可能希望以呈现给客户的形式保留运行余额,因为他拥有余额证据。

最新更新