在postgresql
中,我可以创建一个记录人员类型的表格。
CREATE TABLE IF NOT EXISTS person_vehicle_type
( id SERIAL NOT NULL PRIMARY KEY
, name TEXT NOT NULL
, vehicle_type TEXT
);
此表可能包含
等值 id | name | vehicle_type
----+---------+---------
1 | Joe | sedan
2 | Sue | truck
3 | Larry | motorcycle
4 | Mary | sedan
5 | John | truck
6 | Crystal | motorcycle
7 | Matt | sedan
car_type
列中的值仅限于{sedan
,truck
,motorcycle
}集。
有没有办法在postgresql
中正式确定此限制?
答案 0 :(得分:1)
我个人会使用外键和查找表。
无论如何你可以使用枚举。我建议您阅读文章 PostgreSQL Domain Integrity In Depth :
一些RDBMS(PostgreSQL和MySQL)有一个特殊的枚举类型 确保变量或列必须是某个值列表之一。 这也适用于自定义域。
然而,这个问题在技术上最好被认为是指称 完整性而非域完整性,通常最好强制执行 外键和参考表。将值放在常规中 引用表而不是将它们存储在模式中处理它们 值作为一流数据。修改可能的值集可以 然后用DML(数据操作语言)而不是 DDL(数据定义语言) ....
但是,当可能的枚举值不太可能时 更改,然后使用枚举类型提供一些小优势。
枚举值具有人类可读的名称,但在内部它们是简单的整数。它们不占用太多存储空间。与...竞争 使用参考表的这种效率需要使用 人工整数键,而不是值的自然主键 描述。即使这样,枚举也不需要任何外键 验证或加入查询开销。
枚解和域在任何地方都是强制执行的,即使在存储过程参数中也是如此,而查找表值则不是。参考 表枚举是使用外键强制执行的,仅适用于 表格中的行。
- 醇>
枚举类型定义了一个自动(但可自定义)的订单关系:
CREATE TYPE log_level AS ENUM ('notice', 'warning', 'error', 'severe');
CREATE TABLE log(i SERIAL, level log_level);
INSERT INTO log(level)
VALUES ('notice'::log_level), ('error'::log_level), ('severe'::log_level);
SELECT * FROM log WHERE level >= 'warning';
<强> DBFiddle Demo 强>
缺点:
与外键强制执行的值限制不同,无法从现有枚举类型中删除值。唯一的解决方法是弄乱系统表或重命名枚举,使用所需的值重新创建它,然后更改表以使用替换枚举。不漂亮。