CREATE DOMAIN创建一个新的域。域本质上是一种带有可选约束(在允许的值集合上的限制)的数据类型。 定义一个域的用户将成为它的拥有者。

CREATE DOMAIN name [ AS ] data_type
    [ COLLATE collation ]
    [ DEFAULT expression ]
    [ constraint [ ... ] ]

其中 constraint 是:

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }

参数说明:

  • name :要被创建的域的名称(可以被模式限定)。
  • data_type:域的底层数据类型。可以包括数组指示符。
  • collation :用于该域的可选的排序规则。如果没有指定排序规则,将使用底层 数据类型的默认排序规则。如果指定了COLLATE, 底层类型必须是可排序的。
  • DEFAULT expression : DEFAULT子句为该域数据类型的列指定一个默认值。 该值是任何没有变量的表达式(但不允许子查询)。默认值表达式 的数据类型必须匹配域的数据类型。如果没有指定默认值,那么 默认值就是空值。
    默认值表达式将被用在任何没有指定列值的插入操作中。如果为一个 特定列定义了默认值,它会覆盖与域相关的默认值。继而,域默认值 会覆盖任何与底层数据类型相关的默认值。
  • CONSTRAINT constraint_name :一个约束的名称(可选)。如果没有指定,系统会生成一个名称。
  • NOT NULL :这个域的值通常不能为空值(但是看看下面的注释)。
  • NULL:这个域的值允许为空值。这是默认值。
  • CHECK (expression) :CHECK子句指定该域的值必须满足的完整性 约束或者测试。每一个约束必须是一个产生布尔结果的表达式。 它应该使用关键词VALUE来引用要被测试的值。计算为 TRUE 或者 UNKNOWN 的表达式成功。如果该表达式产生一个 FALSE 结果,会报告一个错误并且该值不允许被转换成该域类型。

当前,CHECK表达式不能包含子查询,也不能 引用除VALUE之外的其他变量。

当一个域有多个CHECK约束,将按照其名字的 字母顺序测试它们。

如果给定一个模式名(例如CREATE DOMAIN mys chema.mydomain ...),那么域将被创建在该指定的模式中。 否则它会被创建在当前模式中。域的名称在其模式中的类型和域之间必须保持唯一。

域主要被用于把字段上的常用约束抽象到一个单一的位置以便维护。例如, 几个表可能都包含电子邮件地址列,而且都要求相同的 CHECK 约束来验证 地址的语法。可以为此定义一个域,而不是在每个表上都单独设置一个约束。

要创建一个域,你必须在其底层类型上拥有USAGE特权。

下面给出使用示例:

-- 创建domain ,性别
postgres@postgres=# CREATE DOMAIN sex_type AS CHAR(1)
postgres@postgres-# CHECK (VALUE IN ('M', 'F'));
CREATE DOMAIN
-- 建表,含有domain类型
postgres@postgres=# create table users(id int primary key, name varchar(50) not null, sex sex_type);
CREATE TABLE
postgres@postgres=# insert into users values(1,'model3', 'F');
INSERT 0 1
postgres@postgres=# insert into users values(2,'modely','M');
INSERT 0 1
-- 违反约束
postgres@postgres=# insert into users values(3,'modelx', 'A');
ERROR:  value for domain sex_type violates check constraint "sex_type_check"
postgres@postgres=# select * from users ;
 id |  name  | sex 
----+--------+-----
  1 | model3 | F
  2 | modely | M
(2 rows)

postgres@postgres=# create domain did as int check( value > 0);
CREATE DOMAIN
postgres@postgres=# create table t2(a did);
CREATE TABLE
postgres@postgres=# insert into t2 values(1);
INSERT 0 1
postgres@postgres=# insert into t2 values(0);
ERROR:  value for domain did violates check constraint "did_check"