如何在另一個表(關係)中儲存對任何其他列(屬性)的引用(包含一個記錄)
TL;DR:如果數據庫模式應該包含所有業務邏輯,那麼如何指定屬性類型是對特定屬性的引用,而不是特定記錄(如外鍵的情況)?
舉個例子,假設我有一個表,其中有一
"Discounts"
列"share"
包含要應用於 column 或 table 值"cost"
的百分比。"price"``"shipping"``"Items"
"Discounts"
還擁有一個外鍵"item_id"
。我需要在
"base"
表"Discounts"
中添加另一列來儲存對 table 列之一的引用"Items"
,併計算該列值的百分比。例如,給定這些值:
Discounts share base item_id ------------------------------------- 50 (item's cost) 3 25 (item's price) 1 100 (item's shipping) 2 Items id cost price shipping ------------------------------- 1 10 40 20 2 55 60 30 3 50 85 10
我希望能夠計算:
- 50 的 50%(第 3 項的成本)
- 40 的 25%(第 1 項的價格)
- 30 的 100%(第 2 項的運輸)
列“base”不應包含引用列的數字(例如 3)或名稱(例如“price”),因為每個表的名稱或順序可能會更改。特別是數據庫對列(屬性)順序或行(記錄/元組)順序沒有任何了解,事實上,RDB 理論斷言*“關係的元組沒有特定的順序,而元組反過來, 對屬性沒有順序。»*
相反,如果我們依賴列名,我們應該強制每個條目包含一個有效的屬性名,並且每當屬性名更改時,我們必須更改其記錄、約束和應用程序的驗證。如果名稱在多個關係中被引用,那麼維護數據庫完整性就變得非常複雜。
這裡的問題是我們沒有在數據庫模式中寫入對屬性名稱的引用(就像我們添加外鍵時一樣),而是寫入數據本身,這似乎是一種非常糟糕的做法,因為它威脅到引用完整性。
如果沒有與數據庫無關的方法來執行此操作,則假設數據庫是 PostgreSQL (v12+)。
我認為您的模型錯誤地代表了您的案例。項目價值元素(成本、價格或運費)似乎本身就是一個實體。我的模型(不知道大局)可能看起來像這樣:
Items ------------------------ Id | int | PK Name | string | ... other attributes ItemValueElements ------------------------ Item ID | int | PK, FK Type | enum | PK -- one of: 'cost', 'price', 'shipping' Value | currency | -- (Item ID, Type) would be the primary key here. Discounts ------------------------ Item ID | int | FK Type | enum | FK Share | decimal |
實際上,折扣通常不適用於單個商品,而是適用於通過不同方式辨識的某些類別的商品,並且您的實際模型會相應更改。
如果對您而言並非如此,並且您確實希望每件商品都有折扣,您可以簡單地將 ItemValueElements 和 Discounts 合併為一個實體。