トランザクションのリストを保持するデータベースを設計しています。取引には2つのタイプがあります。クレジット(残高に追加)とデビット(残高から取得)という名前を付けます。
ほとんどの場合、クレジットトランザクションには有効期限があり、その後、このクレジット残高は無効になり、失われます。
借方取引は、それらがどの貸方取引からのものであるかを保存する必要があります。
賞味期限のある寛大さの余地は常にあります。正確である必要はありません(たとえば、その日の残りの時間まで)。
私の友人と私は2つの異なる解決策を考え出しましたが、どちらを使用するかを決めることはできません。おそらく、皆さんの何人かが私たちを助けてくれるでしょう。
解決策1:
3つのテーブル:Debit、Credit、DebitFromCredit
Debit: id | time | amount | type | account_id (fk)
Credit: id | time | amount | expiry | amount_debited | accountId (fk)
DebitFromCredit: amount | debit_id (fk) | credit_id (fk)
テーブルCreditでは、debitトランザクションが発生するたびにamount_debitedを更新できます。デビットトランザクションが発生すると、DebitFromCreditは、このデビットトランザクションが取り消されたクレジットトランザクションの情報を保持します。
getBalance()
有効期限、金額、amount_debitedに応じて残高を取得する関数があります。したがって、天びんの物理的な保管はありません。毎回計算されます。
期限切れのトランザクションをチェックするcronジョブを追加する機会もあり、タイプとして「期限切れ」の借方トランザクションを追加する可能性もあります。
解決策2
3つのテーブル:Transactions、CreditInfo、DebitInfo
Transactions: id | time | amount (+ or -) | account_id (fk)<br />
CreditInfo: trans_id (fk) | expiry | amount | remaining | isConsumed<br />
DebitInfo: trans_id (fk) | from_credit_id (fk) | amount<br />
テーブルアカウントは、残高を保存する「残高」列を追加します。(別の可能性は、このアカウントのトランザクションの行を合計することです)。
すべてのトランザクション(貸方または借方)はテーブルトランザクションに保存され、金額の符号はそれらを区別します。
クレジットでは、creditInfoに行が追加されます。
デビット時に、1つ以上の行がDebitInfoに追加されます(必要に応じて、複数のクレジットからのデビットを処理するため)。また、クレジット情報の行は「残り」の列を更新します。
cronジョブはCreditInfoテーブルで機能し、期限切れの行が見つかると、期限切れの金額の借方レコードが追加されます。
議論
ソリューション1は、2つのテーブルを区別し、それぞれのデータの取得は非常に簡単です。また、cronジョブは実際には必要ないため(期限切れのデータを借方として追加する場合を除く)、getBalance()
正しい現在の残高を取得します。レポート用のデータを取得するには、何らかの結合が必要です。冗長データはありません。
ソリューション2は、両方のトランザクションを1つのテーブルに保持し、金額は+と-であり、このテーブルは更新されていません。挿入のみ。クレジット情報は、有効期限(cronジョブ)または借方記入時に更新されます。レポート用のデータを取得するための単一テーブルクエリ。ある程度の冗長性。
選択?
どの解決策が良いと思いますか?残高は物理的に保存する必要がありますか、それとも計算する必要がありますか(cronジョブで更新される可能性があることを考慮して)?どちらが速いでしょうか?
また、あなたたちがより良い提案を持っているなら、私たちはそれも聞いてみたいです。