[英]How I store Enumerations in the Database
我時不時要在數據庫中遇到的一件事是名稱如“ MessageType”的單個表的集合。 您看一下它們,結果發現有6行左右沒有外鍵關系。 事實證明,每一次有人都會想到將Enumeration(Enum)類型存儲在數據庫中。 事實證明這不是一個壞主意,因為您可以添加排序選項,軟刪除等,但是為每個表實現單個表是有缺陷的。
“域”(或“類型”)是關系理論的基本組成部分。 根據定義,它是所討論類型的所有可能值的集合。 (除其他事項外。)
在某些情況下,將此類值的集合存儲在表中是不切實際或不必要的。
但是在其他情況下,存儲所有可能值的集合是有意義的。 在SQL數據庫中,您可以將該設置存儲為CHECK約束的一部分。 您也可以將該集合存儲在表中。 將集合存儲在表中的最大好處是,當您驚訝地發現最初不知道是該集合成員的值時,無需更改任何代碼。
因此,在一定的理論水平上,您可以說關系數據庫中的每一列都映射到一個外鍵引用,該引用指向包含所有可能值集合的表。 但是,當需要構建數據庫時,由於不切實際或不必要,這些表中的許多表可能會被淘汰。
其他人可能不會。
我不確定這是否意味着您的意思,但是如果您查看這種表,將不會看到任何外鍵引用。 相關外鍵引用將始終在其他表中,並引用所有可能值的集合。
枚舉實際上是一組查找值的有效值,每個查找值都有一個名稱和一個顯式值-因此您可能會爭辯說每個查找值確實可以很好地映射到引用表。 如果在存儲這些枚舉值的任何地方強制執行外鍵約束,則還應確保數據始終在范圍內。
這取決於您的情況。 我已經在使用“ Enum”表之前完成了應用程序-但是更常見的是,我只是在代碼中強類型化了枚舉,然后在將它們提交到數據庫時將其轉換為文字字符串。
例如
public enum MessageType
{
General,
Comment,
Feedback,
Suggestions
}
我認為沒有正確或錯誤的方法。
將每個枚舉類型存儲在其自己的列中是很好的設計。 即使使用第二列來消除歧義,將來自不同類型的枚舉值存儲在同一列中也是不好的設計。 一旦決定為每種類型使用單獨的列,將該列存儲在其自己的表中的額外成本將降至最低。
我通常在該表中有一個Id字段,並將該Id字段用作對枚舉實例的任何需要的外鍵引用的目標。 這樣的表可以用於驗證和查找。
對於一個大型且復雜的數據庫(其中包含約500個表),將其中約150個表作為查找表並不少見。
我個人認為,如果在其他類型的實體中使用枚舉值,則將枚舉存儲在數據庫中是個好主意。 此外,將每個枚舉存儲在不同的表中非常常見,否則外鍵關系將不正確。
例如,如果MessageType
枚舉具有值:
enum MessageType
{
Alert = 1, /*each next will be incremented by 1*/
Error,
Log
}
然后,對應的表將具有以下結構:
table MessageTypes
{
ID int,
Name varchar(50)
}
在這里, ID
保存我們MessageType
枚舉的整數值(1 =>“ Alert”,2 =>“ Error”,3 =>“ Log”),並在需要時用作外鍵。
此外,在代碼中,無需MessageTypes
地操作MessageTypes
表中的數據,從而最大程度地減少了數據庫之間的數據傳輸大小。
例如,考慮以下數據庫表:
table Messages
{
ID int,
MessageTypeID int /*this is foreign key referring to Messages.ID*/,
Text varchar(100)
}
在代碼中,我們可能會有對應的實體類,如下所示:
class Message
{
int ID { get; set; }
int MessageTypeID { get; set; }
string Text { get; set; }
}
因此,當我們檢索Message
實體時,我們不需要從MessageTypes
表中檢索相應的行,也不需要像MessageType這樣的單獨實體。 相反,我們可以直接使用已知的枚舉值檢查消息類型:
var msg = LoadMessage(id: 101);
if (msg.MessageTypeID == (int)MessageType.Alert)
{
Console.WriteLine("Alert: {0}", msg.Text);
}
我希望這是有道理的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.