VastbaseE100

基于开源技术的HTAP数据库管理系统。性能优异,稳定可靠,提供诸多专属领域特性。

Menu

CREATE DOMAIN

CREATE DOMAIN - 定义一个新域

语法格式

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

其中 constraint 是:

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

说明

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

如果给出了模式名称(例如, CREATE DOMAIN myschema.mydomain …),则会在指定的模式中创建域。否则,它将在当前架构中创建。域名在其架构中存在的类型和域中必须是唯一的。

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

要能够创建域,您必须具有基础类型的 USAGE 权限。

参数说明

  • name

    要被创建的域的名称(可以被模式限定)。

  • data_type

    域的底层数据类型。可以包括数组指示符。

  • collation

    用于该域的可选的排序规则。如果没有指定排序规则,将使用底层 数据类型的默认排序规则。如果指定了COLLATE, 底层类型必须是可排序的。

  • DEFAULT expression

    DEFAULT子句为该域数据类型的列指定一个默认值。 该值是任何没有变量的表达式(但不允许子查询)。默认值表达式 的数据类型必须匹配域的数据类型。如果没有指定默认值,那么 默认值就是空值。 默认值表达式将被用在任何没有指定列值的插入操作中。如果为一个 特定列定义了默认值,它会覆盖与域相关的默认值。继而,域默认值 会覆盖任何与底层数据类型相关的默认值。

  • CONSTRAINT constraint_name

    一个约束的名称(可选)。如果没有指定,系统会生成一个名称。

  • NOT NULL

    这个域的值通常不能为空值(但是看看下面的注释)。

  • NULL

    这个域的值允许为空值。这是默认值。 这个子句只是为了与非标准 SQL 数据库相兼容而设计。在新的 应用中不鼓励使用它。

  • CHECK (expression)

    CHECK子句指定该域的值必须满足的完整性 约束或者测试。每一个约束必须是一个产生布尔结果的表达式。 它应该使用关键词VALUE来引用要被测试的值。计算为 TRUE 或者 UNKNOWN 的表达式成功。如果该表达式产生一个 FALSE 结果,会报告一个错误并且该值不允许被转换成该域类型。 当前,CHECK表达式不能包含子查询,也不能 引用除VALUE之外的其他变量。 当一个域有多个CHECK约束,将按照其名字的 字母顺序测试它们(版本 9.5 之前的Vastbase E100 不遵循任何用于CHECK约束的特定触发顺序)。

注意事项

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

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

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

由于SQL的一般假设是空值是每种数据类型的有效值,因此很难避免此类问题。因此,最佳做法是设计域的约束以允许空值,然后根据需要将列NOT NULL 约束应用于域类型的列,而不是直接应用于域类型。

示例

此示例创建 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
);