在Postgres中,如何限制特定列的可能值?

Dee*_*ets 50 sql postgresql

我想element_type在表(称为discussion)中创建一个允许文本值为"lesson"或"quiz"的列,但如果在该列中插入任何其他值,则会生成错误.

据我所知,我可以element_types使用columns element_id(主键,int)和element_type(唯一的,文本)创建一个单独的表,并foreign_element_id在表discussion引用element_types列中创建一个外键element_id.或者,我可以element_id完全忘记并将其设置element_type为主键.但我想避免创建一个新表.

是否有更简单的方法来限制列中的可能值而不创建新表?

Nul*_*ion 85

你可以添加一个 CHECK CONSTRAINT:

ALTER TABLE distributors 
   ADD CONSTRAINT check_types 
   CHECK (element_type = 'lesson' OR element_type = 'quiz');
Run Code Online (Sandbox Code Playgroud)

虽然IMO更清洁的选择是创建一个ENUM:

CREATE TYPE element_type AS ENUM ('lesson', 'quiz');
Run Code Online (Sandbox Code Playgroud)

  • 优秀.谢谢.作为对我可能像Postgres一样新的其他人的注释,CREATE TYPE创建一个用户定义的类型,可以用作任何其他类型,例如int或text.在这种情况下,可以说:`CREATE TYPE element_type as ENUM('lesson','quiz'); CREATE TABLE讨论(type_of_element element_type;);` (16认同)
  • 值得注意的是,虽然您可以在最近的版本中向ENUM类型添加值,但是没有优雅/简单的方法来删除它们.如果您预计允许值会发生很大变化,我建议您使用检查约束. (5认同)
  • 我们在将 postgresql 枚举映射到 Java 枚举时遇到问题,并决定继续使用“检查” (2认同)

ffr*_*rey 33

shorcut语法是:

ALTER TABLE distributors  
   ADD CONSTRAINT check_types 
   CHECK (element_type IN ('lesson', 'quiz') );
Run Code Online (Sandbox Code Playgroud)

这会将automaticolly转换为:

CONSTRAINT check_types CHECK (element_type::text = ANY (ARRAY['lesson'::character varying, 'quiz'::character varying) )
Run Code Online (Sandbox Code Playgroud)

请享用 ;-)