Oracle
兩個表的外鍵約束
我正在嘗試將以下實體模型付諸實踐:
- 我們有一個 Payments 列表,每個 Payment 屬於某個商店並且屬於某種支付類型*(例如 Store1 中的 10 歐元維護成本,Store2 中的 20 歐元租金)*
- 付款類型是一個類別,例如*(租金、維護、法律費用、許可證)*,每個類別都分配有一個特定的 account_type (例如,budget_legal、budget_monthly、budget_extraordinary),其中多個付款類型可以具有相同的 account_type
- 我們有帳戶:一個帳戶屬於某個帳戶類型的某個商店。所以 Store1 可以有賬戶類型budget_legal、budget_monthly,而Store2 有賬戶類型budget_legal、budget_monthly 和budget_extra
關係模型:
使用http://draw.io/創建的圖像
現在我想要一個約束,即每筆付款必須屬於現有帳戶。我要保證以下幾點:
- 當我更改 Payment_type 的 account_type 時,這種類型的所有付款都將“屬於”各個帳戶。
- 如果我刪除一個帳戶,我想刪除該帳戶中的所有付款(例如刪除外鍵中的級聯)
- 我只能插入/更新付款,以便每次付款都引用有效的 store_id/account_type,它存在於 accounts 表中。
我嘗試過但沒有真正起作用的可能解決方案:
我嘗試將account_type添加到付款中,但隨後我將該欄位翻了一番 - 當我更改付款類型時,我將不得不通過觸發器更改引用的付款。- 但在最好的情況下,我不希望觸發器強制執行數據完整性 - 而且我不希望重複數據儲存。
我試圖在多個表上創建一個外鍵約束/一個將支付與 payment_types 連接起來的視圖。不幸的是,這在 Oracle DBMS 中似乎是不可能的
我試圖在 Payments 上創建一個虛擬列,它從 payment_types 計算值,但虛擬列只能引用同一個表中的列。
先說一些注意事項:
- 考慮到對
Accounts
有unique
限制(account_type, account_store)
,付款似乎只與一個帳戶相關聯。這表明 FK fromPayments
應該引用Accounts
(而不是Stores
)。此更改還將解決問題 #2。- 添加
account_type
到Payments
(並相應地修改外鍵Payment_types
)似乎是最明智的方法,它將解決問題#3。- 這兩項更改將共同解決問題 #1。
- Oracle 沒有
ON UPDATE CASCADE
選項,因此這個問題(更新 Payment_type 的 account_type 以更新相關的 Payments)需要通過更新觸發器或儲存過程(還將檢查相關 Accounts 是否也存在(或已添加)來解決) 適用於所有具有(更新的)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
使用複合鍵。