pun*_*ish 44 postgresql postgresql-9.1
我一直在将MySQL数据库迁移到Pg(9.1),并且已经通过在Pg中创建新数据类型来模拟MySQL ENUM数据类型,然后将其用作列定义.我的问题 - 我可以使用CHECK CONSTRAINT而且会更好吗?实现MySQL ENUM类型以强制行中的特定值条目.可以用CHECK CONSTRAINT完成吗?如果是,它会更好(或更糟)吗?
pun*_*ish 72
根据这里的评论和答案,以及一些初步的研究,我有以下摘要来提供Postgres-erati的评论.非常感谢您的投入.
有三种方法可以限制Postgres数据库表列中的条目.考虑一个表来存储"颜色",您只希望"红色","绿色"或"蓝色"成为有效条目.
枚举数据类型
CREATE TYPE valid_colors AS ENUM ('red', 'green', 'blue');
CREATE TABLE t (
color VALID_COLORS
);
Run Code Online (Sandbox Code Playgroud)
优点是类型可以定义一次,然后根据需要在尽可能多的表中重用.标准查询可以列出ENUM类型的所有值,并可用于生成应用程序表单小部件.
SELECT n.nspname AS enum_schema,
t.typname AS enum_name,
e.enumlabel AS enum_value
FROM pg_type t JOIN
pg_enum e ON t.oid = e.enumtypid JOIN
pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE t.typname = 'valid_colors'
enum_schema | enum_name | enum_value
-------------+---------------+------------
public | valid_colors | red
public | valid_colors | green
public | valid_colors | blue
Run Code Online (Sandbox Code Playgroud)
缺点是,ENUM类型存储在系统目录中,因此需要上述查询来查看其定义.查看表定义时,这些值不明显.并且,由于ENUM类型实际上是与内置NUMERIC和TEXT数据类型分开的数据类型,因此常规数字和字符串运算符和函数不起作用.所以,不能做一个像查询
SELECT FROM t WHERE color LIKE 'bl%';
Run Code Online (Sandbox Code Playgroud)检查约束
CREATE TABLE t (
colors TEXT CHECK (colors IN ('red', 'green', 'blue'))
);
Run Code Online (Sandbox Code Playgroud)
两个优点是,一,"你看到的就是你得到的",也就是说,列的有效值记录在表定义中,两个,所有本地字符串或数字运算符都有效.
外键
CREATE TABLE valid_colors (
id SERIAL PRIMARY KEY NOT NULL,
color TEXT
);
INSERT INTO valid_colors (color) VALUES
('red'),
('green'),
('blue');
CREATE TABLE t (
color_id INTEGER REFERENCES valid_colors (id)
);
Run Code Online (Sandbox Code Playgroud)
本质上与创建ENUM类型相同,除了本机数字或字符串运算符工作,并且不必查询系统目录来发现有效值.需要连接才能链接color_id到所需的文本值.
Gor*_*hen 17
正如其他答案所指出的,检查约束具有灵活性问题,但是在整数id上设置外键需要在查找期间加入.为什么不在参考表中使用允许的值作为自然键?
从punkish的答案中调整架构:
CREATE TABLE valid_colors (
color TEXT PRIMARY KEY
);
INSERT INTO valid_colors (color) VALUES
('red'),
('green'),
('blue');
CREATE TABLE t (
color TEXT REFERENCES valid_colors (color) ON UPDATE CASCADE
);
Run Code Online (Sandbox Code Playgroud)
值与检查约束情况一样以内联方式存储,因此没有连接,但可以轻松添加新的有效值选项,并且可以通过更新现有值实例ON UPDATE CASCADE(例如,如果确定"红色"实际应该是"红色",则更新valid_colors相应地,变化自动传播).
小智 5
外键与检查约束的一大缺点是任何报告或 UI 显示都必须执行连接以将 id 解析为文本。
在一个小型系统中,这不是什么大问题,但是如果您正在使用具有很多小型查找表的 HR 或类似系统,那么这可能是一个非常大的问题,因为为了获取文本而进行了大量连接。
我的建议是,如果值很少且很少更改,则对文本字段使用约束,否则对整数 id 字段使用查找表。
| 归档时间: |
|
| 查看次数: |
28472 次 |
| 最近记录: |