On this page
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 标准。