在Postgresql中,有没有办法将列的值限制为枚举?

时间:2018-01-11 16:50:44

标签: postgresql enums

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列中的值仅限于{sedantruckmotorcycle}集。

有没有办法在postgresql中正式确定此限制?

1 个答案:

答案 0 :(得分:1)

我个人会使用外键和查找表。

无论如何你可以使用枚举。我建议您阅读文章 PostgreSQL Domain Integrity In Depth

  

一些RDBMS(PostgreSQL和MySQL)有一个特殊的枚举类型   确保变量或列必须是某个值列表之一。   这也适用于自定义域。

     

然而,这个问题在技术上最好被认为是指称   完整性而非域完整性,通常最好强制执行   外键和参考表。将值放在常规中   引用表而不是将它们存储在模式中处理它们   值作为一流数据。修改可能的值集可以   然后用DML(数据操作语言)而不是   DDL(数据定义语言) ....

     

但是,当可能的枚举值不太可能时   更改,然后使用枚举类型提供一些小优势。

     
      
  1. 枚举值具有人类可读的名称,但在内部它们是简单的整数。它们不占用太多存储空间。与...竞争   使用参考表的这种效率需要使用   人工整数键,而不是值的自然主键   描述。即使这样,枚举也不需要任何外键   验证或加入查询开销。

  2.   
  3. 枚解和域在任何地方都是强制执行的,即使在存储过程参数中也是如此,而查找表值则不是。参考   表枚举是使用外键强制执行的,仅适用于   表格中的行。

  4.   
  5. 枚举类型定义了一个自动(但可自定义)的订单关系:

  6.   
 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

  

缺点:

     

与外键强制执行的值限制不同,无法从现有枚举类型中删除值。唯一的解决方法是弄乱系统表或重命名枚举,使用所需的值重新创建它,然后更改表以使用替换枚举。不漂亮。