設計一對一的關係
首先,我必須承認我在設計數據庫模式方面沒有豐富的經驗。受到 OOP 的影響,我發現通過將我們擁有的關於對象的資訊劃分為不同的實體,我們可以實現更好的資訊組織。
例如,假設我們有一個籃球運動員。對於每個球員,我們都有一些一般資訊,例如他們的姓名、年齡、他們所扮演的位置等。我們還有一些關於他們在整個職業生涯中的表現的資訊(例如總得分、總蓋帽等)。很明顯,球員和他們的一生數據之間的關係是1:1。
現在讓我們看看這種關係的一些設計選項:
- 最簡單的選擇是將玩家的一般資訊與他們的統計數據包含在一個表格中。但這對我來說似乎雜亂無章;讓我們想像一下,我們有超過 50 列的統計數據。
- 第二個選項是創建一個表 player_stats 並將 player_id 作為主鍵並通過它引用 player 表的主鍵。我認為這被稱為一對一的雙向關係。
- 第三種選擇是在引用他的統計數據的玩家中放置一個外鍵。那將是一對一的無向關係。
- 第四個選項是創建一個結合兩個資訊的連接表。放置唯一的約束確保不會有重複的玩家或統計數據。
所以讓我們總結一下。將資訊分解到不同的表是個好主意嗎?如果是,那麼在一對一關係中應該首選什麼設計?什麼時候?
選項1
這是大多數情況下的首選設計。
選項 2 和 3
根據經驗,盡量避免拆分數據。我在一個應用程序中做到了,但意識到(幾年後)它弊大於利(程式明智)。
這種方法唯一有意義的是“IS A”類型的關係設計。
例如:為像 Michael Jordon 這樣的玩家儲存玩家統計數據的正確方法是使用
BASKETBALL_STATS
、BASEBALL_STATS
和GOLF_STATS
表。每一個“IS A”類型的STATS
。單向
為了維護單向,需要從
STATS
表到PLAYERS
表的外鍵。雙向
對於雙向,您還需要從
PLAYERS
表到STATS
表的 FK,該表在COMMIT
時間而不是 DML 時間(DEFERRABLE INITIALLY DEFERRED
對於 Oracle)進行驗證。當您有多種類型的統計數據時,這會變得有點複雜。
選項 4
當且僅當
STATS
數據是漸變維度 (SCD) 類型 4數據時,我才會使用此設計。在這種設計下,您實際上是在將玩家統計數據的歷史儲存為遊戲/年的進度。編輯在我看來,這個模型對於這種情況甚至沒有意義。相反,您將在表中有一個可以為空的 FK,
PLAYERS
它指向表中的最新行STATS
。您將使用與新統計資訊相同的事務中的正確資訊更新該列。