关于 YMatrix
标准集群部署
数据写入
数据迁移
数据查询
运维监控
参考指南
工具指南
数据类型
存储引擎
执行引擎
流计算引擎
灾难恢复
系统配置参数
索引
扩展
SQL 参考
常见问题(FAQ)
定义一个新域。
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 ...),则域将在指定模式中创建;否则将在当前模式中创建。域名称必须在其所在模式内现有数据类型和域中保持唯一性。
域可将字段的常见约束抽象为单一维护位置。例如,多个表可能包含电子邮件地址列,且均需相同的CHECK约束来验证地址语法。此时应定义域,而非为每个表单独设置约束。
创建域需具备底层类型的USAGE权限。
在将值转换为域类型时,会检查域约束(特别是NOT NULL约束)。即使存在此类约束,理论上属于域类型的列仍可能被读取为空值。例如,在外连接查询中,若域列位于外连接的可空侧,就会出现这种情况。更微妙的例子是:
INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));
空标量子查询将产生一个空值,该值被视为域类型,因此对其不再进行约束检查,插入操作将成功完成。
由于SQL普遍假设空值是所有数据类型的有效值,因此很难避免此类问题。最佳实践是设计域约束时允许空值,然后根据需要对域类型的列应用NOT NULL约束,而不是直接对域类型应用。
YMatrix数据库假定CHECK约束的条件是不可变的,即对于相同的输入值,它们将始终返回相同的结果。正是基于这一假设,才合理地在值首次转换为域类型时检查CHECK约束,而在其他情况下则不进行检查。(这本质上与表CHECK约束的处理方式相同。)
打破此假设的常见方式之一是在CHECK表达式中引用用户自定义函数,随后更改该函数的行为。数据库虽不禁止此操作,但不会检测到域类型中已存储的值是否违反了CHECK约束。这将导致后续的数据库转储和还原操作失败。处理此类变更的推荐方法是:先使用ALTER DOMAIN删除约束,调整函数定义后重新添加约束,从而重新验证存储数据是否符合约束条件。
此示例创建了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
);
CREATE DOMAIN 符合 SQL 标准。