Database-Design

儲存的金融交易是否應該包含一些數據冗餘?

  • June 18, 2021

我目前將金融交易儲存在下表中(為簡潔起見而縮短):

id INT
start DATETIME
end DATETIME
rate INT
usage INT
usage_fee INT
amount INT
commission_pct INT
payout INT
currency VARCHAR(5)

向客戶收取的總金額計算如下: amount = (end - start) * rate + usage * usage_fee

該平台收取以下費用/佣金: commission = amount * (commission_pct / 100)

服務提供商收到的付款是: payout = amount - commission

現在在上表中,儲存支出在技術上是多餘的,因為它可以如上所示計算。我的問題是,關於數據冗餘儲存這些類型的金融交易的常用方式/約定是什麼?

例如,除了它們的總和(金額)之外,我還考慮將(end - start) * rate和的結果單獨儲存在此表中。usage * usage_fee

我看到這樣做的優點是:

  • 將相應金額發送到“支付提供商的 API”時不會出現(舍入)錯誤,即使用者最終支付的金額與數據庫中儲存的金額完全相同,而不是將計算值發送到所述 API
  • 易於查詢和分析

這些專業人士是否有效,或者您會建議我完全規範化表格並在需要時計算值?

我知道根據“數據庫設計原則”對錶格進行規範化是正確的答案,但由於我正在處理財務數據,我不確定我是否 100% 滿意使用計算值。


每筆交易的佣金率並不具體,但收取的佣金百分比將來很可能會發生變化,因此它與每筆交易一起儲存。當然,如果儲存實際的“佣金金額”,則無需儲存佣金百分比。

那個時間點使用的commission_pct 和rate 儲存在表中,這就是為什麼將來為後續交易更改這些不是問題並且永遠不會編輯現有交易的原因。此外,只有一個受控應用程序可以訪問數據庫。如果將來公式發生變化,不計算和儲存結果將是一個問題。我傾向於應用程序計算這些值並一舉儲存“原始”值和計算值。

像這樣儲存計算結果是很常見的,因此您記錄的是金融交易的事實,而不是您認為應該發生的事情。還因為儲存結果允許您隨時間執行調整和更改計算。

儲存支出的一個可能問題是它的計算位置和方式。看起來它將在插入事務的應用程序中完成。

是什麼阻止任何有權訪問該表的人在不計算支出的情況下插入交易?如果應用程序更新交易,例如更改費率或佣金 pct 怎麼辦?儲存的支出將不正確。

一些數據庫可以使用應用程序權限來防止這種情況,即只有擁有更新表權限的應用程序才能這樣做。

存在不儲存計算的支出的解決方案,但存在每個需要支出的人都必須計算它的問題。這意味著所有人都必須為此使用相同的公式。改變公式意味著改變所有這些應用程序——如果你都知道的話。

要麼儲存支出並通過觸發器自動計算,要麼將其設為VIRTUAL自動計算的列(並且不需要儲存)。——阿爾伯特·戈德芬德

引用自:https://dba.stackexchange.com/questions/294456