2010-11-27 68 views
11

我很少看到野外使用的ENUM數據類型;顯影劑幾乎總是隻是使用輔助表看起來像這樣:SQL:ENUM與一對多關係的優點?

CREATE TABLE officer_ranks (
id int PRIMARY KEY 
,title varchar NOT NULL UNIQUE); 
INSERT INTO ranks VALUES (1,'2LT'),(2,'1LT'),(3,'CPT'),(4,'MAJ'),(5,'LTC'),(6,'COL'),(7,'BG'),(8,'MG'),(9,'LTG'),(10,'GEN'); 

CREATE TABLE officers (
solider_name varchar NOT NULL 
,rank int NOT NULL REFERENCES officer_ranks(id) ON DELETE RESTRICT 
,serial_num varchar PRIMARY KEY); 

但是也可以使用用戶定義的類型/ ENUM中所示的相同的事情:

CREATE TYPE officer_rank AS ENUM ('2LT', '1LT','CPT','MAJ','LTC','COL','BG','MG','LTG','GEN'); 

CREATE TABLE officers (
solider_name varchar NOT NULL 
,rank officer_rank NOT NULL 
,serial_num varchar PRIMARY KEY); 

(實施例示出使用PostgreSQL ,但其他RDBMS的語法相似)

我看到使用ENUM的最大缺點是從應用程序中更新更加困難。而且它也可能會讓一個習慣於使用SQL DB的無經驗的開發人員簡單地將其視爲一個桶。

假設信息大多是靜態的(工作日名稱,月份名稱,美國軍隊等級等),使用ENUM是否有優勢?

+0

Duplicate:http://stackoverflow.com/questions/2318123/postgresql-enum-what-are-the-advantages-and-disadvantages – 2010-12-21 18:16:06

回答

6

使用像ENUM這樣的東西的一個缺點是,如果它們不存在於數據表中,則無法獲得所有可用值的列表,除非您在某處硬編碼可用值列表。例如,如果您的OFFICERS表中沒有發佈MG的信息,則無法知道排名是否存在。因此,當BG Blowhard被MG Marjorie-Banks解除時,你將無法進入新任軍官的職位 - 這是一種恥辱,因爲他是現代少將的典範。 :-)當陸軍將軍(五星將軍)出現時會發生什麼?

對於不會更改的簡單類型,我已成功使用域。例如,在我的一個數據庫中,我有一個yes_no_domain定義如下:

CREATE DOMAIN yes_no_dom 
    AS character(1) 
    DEFAULT 'N'::bpchar 
    NOT NULL 
    CONSTRAINT yes_no_dom_check 
    CHECK ((VALUE = ANY (ARRAY['Y'::bpchar, 'N'::bpchar]))); 

分享和享受。

5

我在使用ENUMS時看不到任何優勢。

它們很難維護,並且不提供任何具有正確外鍵的常規查找表不允許您執行的操作。

+2

那麼他們爲什麼存在? – jamieb 2010-11-27 20:02:08

+5

老實說:我不知道。即使是Postgres的開發者在郵件列表中定期承認他們並不真正有用 – 2010-11-27 20:04:39

5

一個小優點可能在於,您在創建ENUM時有一種UDT。用戶定義類型可以在許多其他數據庫對象中正式重用,例如,其他表格,其他類型,存儲過程(在其他RDBMS中)等。

另一個優點是記錄字段的允許值。例子:

  • 是/否領域
  • 公/母場
  • A先生/女士/ MS/DR領域

可能是一個品味的問題。我更喜歡ENUM這些類型的字段,而不是外鍵來查找這樣簡單的概念表。

另一個優點可能是,當您在Java中使用代碼生成或ORM(如jOOQ)時,可以使用ENUM從它生成Java枚舉類,而不是加入查找表或使用ENUM文字的ID

儘管只有少數幾個RDBMS支持正式的ENUM類型,但這是一個事實。我只知道Postgres和MySQL。 Oracle或DB2沒有它。

+0

此外,這是http:// stackoverflow的重複。com/questions/2318123/postgresql-enum-what-are-advantage-and-disadvantage – 2010-11-27 20:35:17

+1

在我看來,使用布爾列可以更好地完成yes/no。像mr/mrs/dr這樣的東西很可能需要本地化,如果使用查找表完成的話(如果本地化在數據庫中完成的話)會更容易。 – 2010-11-27 20:46:42

2

一般來說,枚舉是事情變化不大好,而且它使用略少的資源,因爲沒有FK支票或任何喜歡上插入等

執行使用查找表更優雅和/或傳統,添加和刪除選項比枚舉更容易。批量更改值比枚舉更容易。

所示
13

實施例使用PostgreSQL,但其他RDBMS的具有相似的語法

這是不正確。它不是ISO/IEC/ANSI SQL要求,因此商業數據庫不提供它(您應該提供查找表)。小城鎮的小端落實各種「附加服務」,但不落實城鎮大端的更嚴格的要求或咕嚕聲。

我們沒有將ENUM作爲DataType的一部分,這很荒唐。

ENUMs的第一個缺點是它是非標準的,因此不便攜。

ENUM的第二大缺點是數據庫已關閉。可以在數據庫上使用的數百個報表工具(獨立於應用程序)無法找到它們,因此無法投影名稱/含義。如果您有一個正常的標準SQL查找表,則該問題將被消除。

第三是,當您更改值時,您必須更改DDL。在普通標準SQL數據庫中,只需在查找表中插入/更新/刪除一行。

最後,你不能輕易得到ENUM的內容列表;你可以用查找表。更重要的是,您可以使用矢量執行任何維度事實查詢,而無需從大型事實表和GROUP BY中進行選擇。

2

優點:存儲過程

  • 類型安全:將引發類型錯誤,如果參數不能被脅迫的類型。像:select court_martial('3LT')會自動產生一個類型錯誤。

  • 自定義聯盟秩序:在你的例子中,官員可以排序沒有排名id。

0

那麼,你沒有看到,因爲通常開發人員在編程語言(如Java)中使用枚舉,並且在數據庫設計中沒有與之相對應的對象。

在數據庫中,這樣的枚舉通常是文本或整數字段,沒有約束。數據庫枚舉不會被轉換成Java/C#/等。枚舉,所以開發人員看不到這方面的收益。

有很多非常好的數據庫功能很少使用,因爲大多數ORM工具太原始以至於無法支持它們。