2010-11-27 67 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工具太原始以至于无法支持它们。