CREATE DOMAIN

Posted 丹心明月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CREATE DOMAIN相关的知识,希望对你有一定的参考价值。

CREATE DOMAIN:定义新域。

语法:

CREATE DOMAIN name [ AS ] data_type
[ COLLATE collation ]
[ DEFAULT expression ]
[ constraint [ ... ] ]
where constraint is:
[ CONSTRAINT constraint_name ]
 NOT NULL | NULL | CHECK (expression) 

描述:

CREATE DOMAIN创建一个新的域。域本质上是一种可带约束(对允许值子集的限制)的数据类型。域定义者为域的所有者。

 

如果在创建域时指定了模式(CREATE DOMAIN myschema.mydomain...),则该域在该模式下创建。否则,域创建在当前模式下。域名不可与已有类型及域名重名。

 

域对于将字段上的公共约束抽象到单个位置进行维护非常有用。例如,可能好几个表都有email地址列,均需要使用CHECK约束检查邮件地址。此时可创建一个域进行管理,而无需对每个表都创建检查约束。

 

若要创建域,则需要对底层类型有USAGE权限。

 

参数:

name

    域名。

data_type

    域所使用的底层数据类型。可包含数组说明符。

collation

    域的可选排序规则。若未指定,则使用底层数据类型默认排序规则。如果需要COLLATE选项,那么底层数据必须可排序。

DEFAULT expression

    DEAFULT子句为域数据类型列指定默认值。可使用变量,但不可使用子查询。若未指定默认值,则默认值为空。在insert语句未对列指定值时,使用默认表达式。若为特定列指定了默认值,则覆写域默认值。域默认值会覆写底层数据类型的默认值。

CONSTRAINT constraint_name

    约束名。若未指定,则系统自动生成。

NOT NULL

    限定值非空。

NULL

    限定值可以为空,此为默认行为。

CHECK(expression)

    检查约束指定完整约束或域值需满足的条件。表达式需返回布尔值。需要使用关键字VALUE来制定需要测试的值。返回TRUE或UNKNOWN的值插入成功,否则失败。

    

    当前检查约束不可指定子查询,也不可指定除VALUE之外的变量。如果存在多个检查约束,则根据约束名称排序依次验证。

 

注意事项:

域约束,特别是NOT NULL约束,是在将值转换到域类型时进行检查。故即使定义了非空,域列读取时也可能为空。例如,这可能在外连接查询中发生:域列在外连接的可为空的一边。

 

一个较为微妙的例子:

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

空的标量子查询会产生一个被认为是域类型的空值,故不会进一步进行约束检查,所以该插入语句会成功。

 

因为空值被认为可以是任意类型,所以很难规避此类问题。故最佳实践是首先定义一个允许空值的域类型,然后在域类型的列上定义非空约束,而非直接在域上定义非空。

 

PostgreSQL假定检查约束条件为固定的,即对于同一输入必为相同输出。而打破此假设的一个场景是:在检查约束中引用用户自定的函数,而后期又更改了函数定义。PostgreSQL虽然不禁止这样做,但为避免造成混淆,建议修改引用函数的最佳实践是:首先删掉该检查约束;然后修改引用的函数定义;最后再重新创建该检查约束。

 

示例:

该示例创建 us_postal_code数据类型,然后创建使用该类型的表:

CREATE DOMAIN us_postal_code AS TEXT

CHECK(

VALUE ~ '^\\d5$'

OR VALUE ~ '^\\d5-\\d4$'

);


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

);

兼容性:

CREATE DOMAIN符合SQL标准。

 

参见:

ALTER DOMAINDROP DOMAIN

 

 

以上是关于CREATE DOMAIN的主要内容,如果未能解决你的问题,请参考以下文章

[reproduce]How to Create Domain in Windows Server 2012.

Laravel:错误 InvalidArgumentException

Domain 表达式的用法

Python RuntimeWarning:长标量中遇到溢出

OpenCV 函数学习14-图像与标量相加(cv2.add)

GraphQL使用之graphql-java自定义标量类型