Postgresql

如何在另一個表(關係)中儲存對任何其他列(屬性)的引用(包含一個記錄)

  • August 12, 2020

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 合併為一個實體。

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