CREATE DOMAIN

CREATE DOMAIN-定义一个新域

Synopsis

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

where constraint is:

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

Description

CREATE DOMAIN创建一个新域。域本质上是具有可选约束(对允许的值集的约束)的数据类型。定义域的用户将成为其所有者。

如果提供了架构名称(例如CREATE DOMAIN myschema.mydomain ...),则将在指定的架构中创建域。否则,它将在当前架构中创建。域名在其架构中现有的类型和域之间必须唯一。

域对于将字段上的常见约束抽象到单个位置进行维护非常有用。例如,几个表可能包含电子邮件地址列,所有这些列都需要相同的 CHECK 约束来验证地址语法。定义一个域,而不是单独设置每个表的约束。

为了能够创建域,您必须对基础类型具有USAGE特权。

Parameters

  • name

    • 要创建的域的名称(可选的模式限定)。
  • data_type

    • 域的基础数据类型。这可以包括数组说明符。
  • collation

    • 域的可选归类。如果未指定排序规则,则使用基础数据类型的默认排序规则。如果指定了COLLATE,则基础类型必须可排序。
  • DEFAULT expression

    • DEFAULT子句为域数据类型的列指定默认值。该值是任何无变量的表达式(但不允许子查询)。默认表达式的数据类型必须与域的数据类型匹配。如果未指定默认值,则默认值为空值。

默认表达式将在未为列指定值的任何插入操作中使用。如果为特定列定义了默认值,它将覆盖与域关联的任何默认值。反过来,域默认值将覆盖与基础数据类型关联的任何默认值。

  • CONSTRAINT constraint_name

    • 约束的可选名称。如果未指定,系统将生成一个名称。
  • NOT NULL

    • 该域的值被防止为空(但请参见下面的 Comments)。
  • NULL

    • 该域的值允许为空。这是默认值。

此子句仅用于与非标准 SQL 数据库兼容。不建议在新应用程序中使用它。

  • CHECK (expression)

    • CHECK子句指定完整性约束或测试域必须满足的值。每个约束必须是产生布尔结果的表达式。它应使用关键字VALUE来引用要测试的值。评估为 TRUE 或 UNKNOWN 的表达式成功。如果表达式产生 FALSE 结果,则会报告错误,并且不允许将该值转换为域类型。

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

当一个域具有多个CHECK约束时,将按名称的字母 Sequences 对它们进行测试。 (对于CHECK约束,PostgreSQL 9.5 之前的版本不遵循任何特定的触发 Sequences.)

Notes

在将值转换为域类型时,将检查域约束,尤其是NOT NULL。尽管存在此类约束,但名义上属于域类型的列仍可能会读取为 null。例如,如果域列位于外部联接的可为空的一侧,则可能在外部联接查询中发生。一个更微妙的例子是

INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));

空的标量子 SELECT 将产生一个空值,该空值被认为是域类型的,因此不会对其应用进一步的约束检查,并且插入将成功。

由于 SQL 普遍认为 null 值是每种数据类型的有效值,因此很难避免此类问题。因此,最佳实践是设计域的约束,以便允许使用空值,然后根据需要将NOT NULL约束应用于域类型的列,而不是直接应用于域类型。

PostgreSQL 假定CHECK约束的条件是不可变的,也就是说,对于相同的 Importing 值,它们将始终给出相同的结果。仅当将值首先转换为域类型时才检查CHECK约束是合理的,而在其他时候则不行。 (这与对表CHECK约束的处理基本上相同,如Section 5.3.1中所述。)

break 此假设的常见方法的一个示例是在CHECK表达式中引用用户定义的函数,然后更改该函数的行为。 PostgreSQL 不允许这样做,但是它不会通知是否存在违反CHECK约束的域类型存储值。这将导致随后的数据库转储和重新加载失败。推荐的处理此类更改的方法是删除约束(使用ALTER DOMAIN),调整函数定义并重新添加约束,从而根据存储的数据对其进行重新检查。

Examples

本示例创建us_postal_code数据类型,然后在表定义中使用该类型。正则表达式测试用于验证该值看起来像是有效的美国邮政编码:

CREATE DOMAIN us_postal_code AS TEXT
CHECK(
   VALUE ~ '^\d{5}$'
OR VALUE ~ '^\d{5}-\d{4}$'
);

CREATE TABLE us_snail_addy (
  address_id SERIAL PRIMARY KEY,
  street1 TEXT NOT NULL,
  street2 TEXT,
  street3 TEXT,
  city TEXT NOT NULL,
  postal us_postal_code NOT NULL
);

Compatibility

命令CREATE DOMAIN符合 SQL 标准。

See Also

ALTER DOMAIN, DROP DOMAIN