2011-05-25 112 views
21

僅供參考:我明確指SQL Server 2000-8和C#。所以支持MySql這樣的枚舉的DBMS不是我的問題的主題。將枚舉值存儲在數據庫中

我知道這個問題已經在SO中多次提出過。但是,我仍然看到在答案中採用了不同的方法來將枚舉值存儲在db中。在代碼

  1. 保存枚舉如在分貝int和提取枚舉值(使用反射或枚舉描述屬性):
    這是我通常使用的方法。問題是當我試圖從SSMS中的數據庫查詢時,檢索到的數據很難理解。

  2. 將枚舉保存爲字符串(varchar)並將其轉換回代碼中的int。
    其實,這可能是最好的解決方案。但是(不要笑!)它感覺不對。我不確定這些缺點。 (除了通常可以接受的db中的更多空間)那麼還有其他方法反對這種方法?

  3. 在db中有一個單獨的表,它與代碼的枚舉定義同步並在主表和枚舉表之間建立外鍵關係。
    問題是,當以後應該添加另一個枚舉值時,代碼和數據庫都需要更新。此外,可能會有錯別字,這可能是一種痛苦!

所以一般時,我們可以接受第二液對數據庫的開銷,什麼是存儲在數據庫枚舉值的最佳方式是什麼?有關於此的一般定義的設計模式規則嗎?
謝謝。

回答

18

沒有明確的設計規則(我知道),但我更喜歡方法1。

  1. 是我喜歡的方法。這很簡單,枚舉通常足夠緊湊,我開始記住數字的意思。
  2. 它更具可讀性,但可以在您想要的時候阻礙重構或重命名您的枚舉值。你失去了你的代碼的一些自由。突然之間,你需要讓一個DBA參與(取決於你在哪裏/如何工作)只是爲了改變一個枚舉值,或者隨之而來。解析一個枚舉也有一些性能影響,因爲像Locale這樣的東西起作用,但可能忽略不計。
  3. 解決了什麼問題?除非您想要添加聯接的開銷,否則表中某個表中仍然有不可讀的數字。但有時候,這也是正確的答案,這取決於數據的使用方式。

編輯: 克里斯的評論有一個很好的一點:如果你這樣做下去的數值方法,你應該明確地指定值,以便可以重新排序它們。例如:

public enum Foo 
{ 
    Bar = 1, 
    Baz = 2, 
    Cat = 9, 
    //Etc... 
} 
+0

嗯,你是對的。第2號導致麻煩如果我們想要重命名枚舉值。 +1謝謝! – Kamyar 2011-05-25 16:39:19

+2

如果您重新排列枚舉,則1號會導致麻煩。 – 2011-05-25 16:56:41

+3

@Chris:然後明確定義值。 – vcsjones 2011-05-25 16:57:44

7

一個想法,我見過哪個是你的選項3或多或少

  • 一個數據庫中的表(外鍵等)
  • 的匹配枚舉在客戶端代碼
  • 一個啓動檢查(通過數據庫調用),以確保它們符合

數據庫表表只能有一個觸發器或檢查約束以降低更改風險。它不應該有任何寫權限,因爲數據綁定到一個客戶端代碼版本,但它增加了一個安全係數,以防DBA鬆了一口氣

如果您有其他客戶端正在閱讀代碼(這很常見),那麼該數據庫具有完整的數據。

+0

「加入」開銷如何?這值得麼? – Kamyar 2011-05-25 16:58:48

+5

@Kamyar:在數據庫引擎中加入開銷?你在開玩笑吧? – gbn 2011-05-25 16:59:20

+2

是不是造成開銷?在許多文章中使用較少的連接建議。 (只要它不會影響正常化*非常糟糕*)例如:http://www.sql-server-performance.com/2007/database-design/ – Kamyar 2011-05-25 17:04:57

相關問題