什麼時候將重複數據移動到參考表中是有益的?
如果有來自某個有限集合的值的列
S
,例如S = { alive, dead, unknown }
對於表life_state
中的列,persons
那麼添加參考表何時有益?選項:
life_state
在列中儲存重複的靜態數據
- 簡單字元串:應用層級別的程式碼需要存在才能獲取可能的數據值,因為
SELECT DISTINCT
可能會失去一些值。ENUM
:如果要獲取所有可能的數據值,life_state
則需要執行SHOW COLUMN..
fromINFORMATION_SCHEMA
以獲取所有可能的數據值並在應用程序層級別解析該數據或在應用程序層級別具有重複程式碼。如果需要添加一個新的 life_state 值,我們需要將整個表添加到ALTER
表中,並在更改過程中鎖定整個表。life_state
如果有必要,不能為每個值儲存額外的數據。規範化創建一個引用表
life_states
和一個連結表回persons
表。可能的值可以從SELECT name from life_states;
其中返回 3 行。現在需要額外的連接來獲取life_state
任何persons
實例。這不僅速度較慢,而且在應用層級別需要更長的查詢/更多程式碼。如有必要,可以輕鬆添加任何其他值,儘管這不是預期的。此外,如果需要將一些其他數據添加到 life_state 類型,則可以輕鬆添加。其他注意事項:
- INT/ENUM 索引可能更快/佔用更少的空間字元串。
相關討論:
什麼時候將重複數據移動到參考表中是有益的?
- 當引用數據獨立於引用數據存在時。在這個例子中,在問題域中了解可能的生命狀態是否有用,即使
persons
.- 當值只能從已知的有限集合中得出時。這通常被稱為“參考數據”。外鍵約束可以強制執行此操作。
- 當必須在兩個(或更多)規範化實體之間維護參照完整性時。這將用於事先不知道值的事務數據。例如,應用程序允許在執行時添加新使用者,並且
last_updated_userid
在每個表上都有。同樣,外鍵將強制執行此操作。- 當發現僅依賴於 life_state 的其他域值時。這是通常的關鍵依賴規範化。
- 當需要元數據時,例如
is_active
“軟刪除”而不是從系統中完全刪除值。儘管習慣上為引用表創建代理鍵,但這不是必需的。對於給出的範例,參考表可能有一個包含三行的七字元列。然後,人類可讀的值將出現在引用表中。這將避免加入引用表的需要。
這個答案主要集中在
ENUM
適用於 MySQL 的類型的使用上,因為它是我似乎使用它們的地方。您已經通過您在自己的文章底部突出顯示的主題回答了您自己的問題 - 這一切都在這裡進行了解釋,即
ENUM
s 是邪惡的:-)!數據庫中的數據應儲存在表中 - 有關數據庫管理的數據應儲存在系統表(數據字典)中。如果您想了解 中的內容
ENUM
,您必須查詢系統表。我的建議是對超過 2 個值的所有內容都使用表格 - 即使這樣,也只需看看圍繞這個問題的性別辯論。
VIEW
正如您所指出的執行緒中所指出的那樣,您可以通過使用s 預連接一些常用的參考表來減輕連接中的一些繁重工作。另外,你的參考表可以包含詳細的描述——那些合約程序員不需要記住任何關於晦澀程式碼的含義的事情!基本上,我不明白為什麼要
ENUM
在數據庫中使用 an ——我已經有一段時間沒有程式了,所以我不太熟悉在語言中使用它們的利弊!