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

时间:2018-06-09 19:44:05

标签: sql database postgresql accounting

我们正在构建一个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

我们还有一个user表,其中包含balance列,当用户发出呼叫,短信费用或退款时,我们会减少这一列。我们会在用户为其帐户付款时将其递增(CHARGE,如上所述)。

但是,我认为我们需要的东西比单一的平衡数字更具弹性,而这些平衡数字会在代码中得到更新。

一个改进是使用触发器而不是代码更新平衡数字。

另一种方法是计算用户在多个表格中的总成本和付款,并对该批次求和。随着表格增长到1000多个交易,我可以想象这会变得很慢。

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

1 个答案:

答案 0 :(得分:1)

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

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