web-dev-qa-db-ja.com

2つのテーブルに対する外部キー制約

私は次のエンティティモデルを実践しようとしています:

  1. 支払いのリストがあり、各支払いは特定のストアに属し、特定の支払いタイプです(例:Store1で10€のメンテナンスコスト、Store2で20€のレンタル)

  2. 支払いタイプは、(賃貸料、メンテナンス、法的費用、ライセンス)のようなカテゴリであり、各カテゴリには確実なaccount_typeが割り当てられます(eg budget_legal、budget_monthly、 budget_extraordinary)複数の支払いタイプが同じaccount_typeを持つことができます

  3. アカウントがあります:アカウントは、特定のアカウントタイプの特定のストアに属しています。したがって、Store1はアカウントタイプbudget_legal、budget_monthlyを持つことができ、Store2はアカウントタイプbudget_legal、budget_monthlyおよびbudget_extraを持つことができます

関係モデル:

Diagram showing Relationship Model

http://draw.io/で作成された画像

ここで、各支払いが既存のアカウントに属している必要があるという制約が必要です。 以下を保証したいと思います:

  1. Payment_typeのaccount_typeを変更すると、このタイプのすべての支払いはそれぞれのアカウントに「属します」。

  2. アカウントを削除した場合、このアカウントのすべての支払いを削除したい(外部キーのカスケードの削除など)

  3. Paymentsを挿入/更新できるのは、支払いごとに、accountsテーブルに存在する有効なstore_id/account_typeを参照するためだけです。


私が試したが実際には機能しない可能性のある解決策:

account_typeを支払いに追加しようとしましたが、フィールドを2倍にしました-支払いタイプを変更すると、参照されている支払いを変更する必要がありますトリガーを介して。 -しかし、最良のケースでは、トリガーによってデータの整合性を強制したくありません-重複したデータストレージを必要としません。

複数のテーブル/ p​​ayment_typesで支払いを結合するビューに外部キー制約を作成しようとしました。残念ながら、これはOracle DBMSでは不可能のようです

Paymentsに仮想列を作成しようとしました。これは、payment_typesから値を計算しますが、仮想列は同じテーブルの列しか参照できません。

2
Falco

最初にいくつかのメモ:

  • Accountsには(account_type, account_store)に対するunique制約があることを考えると、支払いは1つのアカウントにのみ関連付けられているようです。これは、PaymentsからのFKがAccountsStoresではなく)を参照する必要があることを示唆しています。この変更により、問題#2も解決されます。

  • account_typePaymentsに追加する(それに応じてPayment_typesへの外部キーを変更する)は、最も賢明なアプローチのようであり、問​​題#3を解決します。

  • 2つの変更を一緒にすると、問題#1が解決されます。

  • OracleにはON UPDATE CASCADEオプションがないため、この問題(Payment_typeのaccount_typeを更新して関連するPaymentsを更新する)には、更新トリガーまたはストアドプロシージャ(関連するアカウントもチェックする)で対処する必要があります。 (更新された)account_typeの支払いがあるすべてのストアに存在する(または追加される)。

Account_typesテーブルもあると想定した場合の推奨される設計(いくつかの列の名前を変更しましたが、それはあなたとあなたの好み/規則次第です):

Account_types
---------------
account_type_id  PK


Payment_types
---------------
account_type_id  PK, FK -> Account_types
payment_type_id  PK


Stores
--------
store_id         PK


Accounts
---------------
account_type_id  PK, FK1 -> Account_types
account_id       PK
store_id             FK2 -> Stores


Payments
---------------
payment_id       PK
amount
account_type_id      FK1, FK2 
payment_type_id      FK1 -> Payment_types
account_id           FK2 -> Accounts

Paymentsの両方の外部キーがどのように複合キーを使用するかに注意してください。

enter image description here

3
ypercubeᵀᴹ