Postgresql
約束輸入值
我正在努力限制我的 Postgres 數據庫中某些欄位的輸入,並且我有一個使用
ENUM
這樣的工作解決方案:CREATE TYPE label AS ENUM ('foo','bar');
但是,我正在四處瀏覽並尋找使用以下方法的替代方法:
- 約束(例如
CHECK (type IN ('foo','bar'))
)- 觸發器(慢,從我讀過的)
- 外鍵
使用這兩種方法的優點/缺點是什麼,這些方法中的任何一種更可取嗎?我不一定要問哪個是“最好的”方法,只是使用這些方法可能會出現什麼樣的問題,即。我知道與其他方法相比,使用觸發器可能會很慢,但也許可以處理一些更複雜的輸入條件。
也許不是所有的差異,但在我看來最重要的是:
- enum vs text/varchar + 檢查約束。
- 列舉值在內部儲存為整數,因此儲存要求不同
- ordering :列舉值的順序對應於在創建類型期間輸入值的順序,因此對於
enum ('small', 'big')
small < big; 對於文本列'big'<'small'
- 列舉與外鍵
- 在性能方面,它們的行為應該非常相似,但是您可以通過例如禁用所有觸發器或更改會話複製角色來繞過外鍵約束
- 從數據模型的角度來看,存在更大的差異。如果某物具有屬性、需要跟踪、可能以任何一種方式進行修改,則應將其作為單獨的實體儲存在其自己的表中。如果它只是一個屬性,例如很多情況下的顏色,那麼將它儲存為列舉類型就可以了。
觸發器不是實現檢查約束的正確工具。它們增加了複雜性,隱藏了邏輯,增加了維護成本。在某些情況下,它們是“必要的邪惡”,但絕對不應該僅僅將它們用於做檢查約束可以做的事情。