我们正在构建一个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
表格包含debit
,credit
和balance
列。这当然会在行之间产生传递依赖关系,如果寻求一个很好的规范化数据库,这并不是很好。这也意味着我们要重复数据,但在现实世界中这是一个可以接受的权衡吗?
答案 0 :(得分:1)
您可以使用实体化视图避免重复数据。请注意,更新余额(以任何方式 - 通过应用程序,触发器,部分运行余额)已经重复数据。因此,您应该运行一些验证程序来警告差异。这样的验证程序应该进行所有计算,因此它们也可以填充物化视图。
但是,实际解决方案取决于您需要这些数据的频率。例如,如果您每月提取所有客户余额以进行帐单结算,则不要复制它们。但是,如果您在每次客户操作后打印余额,例如在某种交易确认中(如生成的PDF和通过电子邮件发送给客户),您可能希望以呈现给客户的形式保持运行余额,因为他拥有余额证据。