2

从 8.3 开始的 PostgreSQL 知道Enumerated Types

简单的问题:8.2(.9) 也知道它们吗?如果没有,可以用什么代替?

4

2 回答 2

5

8.2 不支持枚举类型。

作为替代方法,可以使用引用了列出可能值的表的列textforeign key

CREATE TABLE fruit_enum (
    fruit text primary key
);

INSERT INTO fruit_enum(fruit) VALUES
('apple'),('pear'),('grape');

CREATE TABLE basket (
    -- ... blah columns ...
    fruit text,
    -- ... blah columns ...
    CONSTRAINT fruit_fk FOREIGN KEY (fruit) REFERENCES fruit_enum(fruit)
);

这是经典的关系公式,通常比使用enum无论如何更可取。枚举在某些客户端应用程序中处理起来很痛苦,而且 Pg 目前也不支持从它们中删除值。

以下是上述的工作原理:

regress=# INSERT INTO basket(fruit) VALUES ('apple');
INSERT 0 1
regress=# INSERT INTO basket(fruit) VALUES ('cider');
ERROR:  insert or update on table "basket" violates foreign key constraint "fruit_fk"
DETAIL:  Key (fruit)=(cider) is not present in table "fruit_enum".
regress=# 

如果您愿意,可以通过整数 ID 间接枚举,其中外键指向枚举表的 ID,而不是枚举值。就我个人而言,我不喜欢这种方法,尽管它实际上只是一种真正的“枚举”,因为获取值总是需要昂贵的JOIN查询或子查询,而且通常节省的空间很少。

或者,正如@a_horse_with_no_name 所指出的,一个简单的CHECK约束通常就足够了:

CREATE TABLE basket (
    -- ... blah columns ...
    fruit text,
    -- ... blah columns ...
    CONSTRAINT fruit_in_allowed_list CHECK (fruit IN ('apple', 'pear', 'grape'))
);

与外键方法(但与枚举不同)一样,这是 SQL 标准,应该适用于任何数据库。

另外,说真的,8.2?那是生命的终结,可悲的是,已经过时了。制定紧急升级计划。

于 2012-09-18T14:31:01.920 回答
1

枚举是在 8.3 中引入的
这里是发行说明:http ://www.postgresql.org/docs/8.3/static/release-8-3.html

8.2 的数据类型记录在这里:http ://www.postgresql.org/docs/8.2/static/datatype.html

但是无论如何你都不应该使用 8.2(实际上我也不推荐 8.3)

于 2012-09-18T14:13:38.560 回答