YashanDB constraint 语法



constraint 用于对表中的数据进行指定规则的约束定义,只有符合约束定义的数据才能被生成,否则系统将会提示违反约束错误。
约束基于列字段定义,被应用于 CREATE TABLE、ALTER TABLE 等与列字段属性定义相关的语法中。
根据在语句中位置不同,YashanDB 提供了行内(inline_constraint)和行外(out_of_line_constraint)两种定义约束的方法,但 NOT NULL 约束项只能作为行内约束被定义。
inline_constraint
行内约束,即在定义列字段属性的同时为其定义约束项。
可通过 CONSTRAINT constraint_name 指定约束项的名称,省略则由系统生成默认名称。
可以在行内定义的约束项有:
UNIQUE:适用于所有表
PRIMARY KEY:适用于所有表
FOREIGN KEY:适用于 HEAP 表
CHECK:适用于 HEAP 表、TAC 表
NOT NULL:适用于所有表
示例(HEAP 表)
Copied!
示例(TAC 表)
Copied!
示例(LSC 表)
Copied!
out_of_line_constraint
行外约束,即不在某一个列字段的属性定义中,而是独立定义。
可通过 CONSTRAINT constraint_name 指定约束项的名称,省略则由系统生成默认名称。
可以在行外定义的约束项有:
UNIQUE:适用于所有表
PRIMARY KEY:适用于所有表
FOREIGN KEY:适用于 HEAP 表
CHECK:适用于 HEAP 表、TAC 表
示例(HEAP 表)
Copied!
示例(TAC 表)
Copied!
约束项
# not null
为某个列字段定义非空约束项,表示要求该列字段上的值不能为空。
NULL 或 NOT NULL 仅支持在行内约束中定义。
HEAP 表不为空时不能新建 NOT NULL 约束的列。
NULL 并不定义约束,只是显式允许列包含 null。
如果既不指定 NOT NULL 也不指定 NULL,则默认值为 NULL。
# unique
为某个列字段或某些列字段组合定义唯一约束项,表示要求该列字段或列字段组合上的值在当前表中无重复。
如下为添加唯一约束项的限制:
当该列字段或列字段组合上已存在重复的数据时,无法成功添加此约束项。
唯一约束项添加成功后,系统将会自动创建一个基于唯一项字段的唯一索引;若该列字段或列字段组合上已存在索引(包括唯一索引和非唯一索引),则不会创建。
分布式部署中建 Sharded 表时,如果同时有多个唯一约束键,例如主键或唯一键,则限制所有的唯一约束键必须至少有一个公共字段 (默认的分区键取唯一约束键的公共子集中的第一个恰当的数据类型的字段),如不满足则返回错误。
分布式部署中在 Sharded 表中增加唯一性约束(包括主键约束和唯一约束),也必须包括分区键。
# primary key
为某个列字段或某些列字段组合定义主键约束项,表示该列字段或列字段组合将作为表的主键。
由于行内约束是针对某一个列字段定义,因此在行内约束中只能定义单列主键,多列组合主键在行外约束中定义。
如下为添加主键约束项的限制:
主键拥有非空性特征,因此当该列字段或列字段组合中的任一列字段上存在空数据时,无法成功添加此约束项。
主键拥有唯一性特性,因此当该列字段或列字段组合上存在重复的数据时,无法成功添加此约束项。
一个表上只能有一个主键,因此当该列字段或列字段组合所在表已存在主键时,无法成功添加此约束项。
主键添加成功后,系统将会自动创建一个基于主键字段的唯一索引;若该列字段或列字段组合上已存在索引(包括唯一索引和非唯一索引),则不会创建。
# check
CHECK 约束用于对要插入表的数据进行条件检查,只有条件返回为 true 时,数据才能被成功插入表中。
当对一个已存在数据的表添加新的 CHECK 约束项时,系统将对现有数据也执行 CHECK 条件检查(在指定了 NOVALIDATE 时不检查),当存在未通过检查的数据时,无法成功添加此约束项。
在行内约束中,CHECK 的条件内容只能指定当前列字段,条件包含多列的 CHECK 在行外约束中定义。
CHECK 的条件可以包含的内容描述请参考 SQL 通用语法condition。
# foreign key
为一个表(子表)的列字段或列字段组合建立到另一个表(父表)的外键约束,表示子表中该列字段或列字段组合上的值必须在父表对应的列上存在,若子表上的值为 NULL,则认为在父表上存在对应值,符合外键约束。
由于行内约束是针对某一个列字段定义,因此在行内约束中只能定义单列外键,多列组合外键在行外约束中定义。
使用外键的约束如下:
不能为临时表建立 FOREIGN KEY,也不能为其他表建立关联到临时表的 FOREIGN KEY。
加密列不能创建 FOREIGN KEY。
# references_clause
在定义外键约束时,REFERENCES 指定了外键指向的父表,及父表中与子表外键列一一对应的列字段。若仅标识父表名而省略列名,则外键会自动引用父表的主键并且外键列与主键列需要一一对应。
以下为添加外键约束项的限制:
外键约束要求子表中外键列上的数据在父表对应列上必须存在,在对一个已存在数据的子表添加新的外键约束项时,系统将对子表中的现有数据执行此项检查(在指定了 NOVALIDATE 时不检查),当存在未通过检查的数据时,无法成功添加此约束项。
外键约束要求父表对应列上的数据满足唯一性约束(该对应列上已定义 PRIMARY KEY 或 UNIQUE 约束项),否则无法成功添加此约束项。
当子表外键列到父表对应列的外键约束已经存在时,无法成功添加此约束项。
# on delete
在建立外键约束后,当对父表对应列上的某个值进行删除操作时,系统将检查该值在子表外键列上是否存在,如存在,该父表上的数据不允许删除。而在约束定义里指定了 ON DELETE 后,系统将允许前述对父表的操作,并同时根据不同选项执行如下操作:
指定 ON DELETE RESTRICT(默认也是 RESTRICT)创建外键后,对子表中存在数据的父表数据执行删除将报错。
指定 ON DELETE CASCADE 创建外键后,对子表中存在数据的父表数据执行删除将成功,且对子表中对应的数据也进行删除。
指定 ON DELETE SET NULL 创建外键后,对子表中存在数据的父表数据执行删除将成功,且对子表中对应的数据置空。
Note:
子表需建立外键的列字段上存在 NOT NULL 约束项时,不能指定 ON DELETE SET NULL 选项创建外键。
此外,系统还提供如下仅用于语法兼容的选项:
ON DELETE NO ACTION(行为与 RESTRICT 一致)
# on update
在建立外键约束后,当对父表对应列上的某个值进行更新操作时,系统将检查该值在子表外键列上是否存在,如存在,该父表上的数据不允许更新。而在约束定义里指定了 ON UPDATE 后,系统将允许前述对父表的操作,并同时根据不同选项执行如下操作:
指定 ON UPDATE RESTRICT(默认也是 RESTRICT)创建外键后,对子表中存在数据的父表数据执行更新将报错。
指定 ON UPDATE CASCA DE 创建外键后,对子表中存在数据的父表数据执行更新将成功,且对子表中对应的数据也进行更新。
指定 ON UPDATE SET NULL 创建外键后,对子表中存在数据的父表数据执行更新将成功,且对子表中对应的数据置空。
Note:
子表需建立外键的列字段上存在 NOT NULL 约束项时,不能指定 ON UPDATE SET NULL 选项创建外键。
约束项属性
YashanDB 提供一系列选项用于定义某个约束项的属性,其中如下选项只用于语法兼容,并无实际含义:
NOT DEFERRABLE
INITIALLY IMMEDIATE
RELY|NORELY
# using_index_clause
该语句只作为 PRIMARY KEY 或 UNIQUE 约束项的属性选项使用,用于指定约束项对应的索引或索引属性,对其他约束项使用本语句将报错。
YashanDB 中,创建 PRIMARY KEY 或 UNIQUE 约束项时,系统将自动创建一个对应的唯一索引(如该唯一索引已存在则不会创建)。使用本语句将系统自动的操作修改为人工指定,所实现效果略有差异,具体见下面描述。
# using index
该语句仅用于已有约束项为 disable 的情况,将该约束项置为 enable,并自动创建索引,索引名称等同约束名称。
# using index [schema.]index_name
为约束项指定一个已有的索引,该索引必须满足以下条件:
必须为一个唯一索引。
索引基于的表和列与约束项必须一致。
不能为倒序索引。
通过此种方式指定的索引,与自动创建的索引的差别为:如后续对约束项进行删除操作,自动创建的索引会随之删除,而此种方式指定的索引并不会被删除。
示例(HEAP 表)
Copied!
# using index index_attr_clause
使用本语句表示在创建约束项时,仍由系统自动创建唯一索引,但对该索引的相关属性进行指定。
在不使用 using_index_clause 且不存在唯一索引时,系统在创建主键时会自动创建一个唯一索引,该索引所有属性均采用默认值,例如索引的表空间将使用和表所在的表空间,使用本语句则可以避免单独构建索引的繁琐,同时也可以满足将索引和表进行物理隔离等实际需求。
需注意的是,使用本语句的前提是约束项列上不存在唯一索引,否则系统并不是直接采用该索引,而是返回失败。
index_attr_clause
指定索引属性的语句,其语法与CREATE INDEX中的 index_attr_clause 一致。
示例(HEAP 表,单机 TAC 表)
Copied!
# using index create_index_clause
使用本语句等同于由系统自动创建唯一索引,但与系统自动创建采用默认值不同的是,本语句可以指定索引的名称、属性等各信息。
create_index_clause
创建索引的语句,除无法创建倒序索引之外,其余语法与CREATE INDEX一致。
需注意的是,当约束项列上已存在唯一索引时,create_index_clause 中的 index_name 必须与已存在索引同名,且 index_attr_clause 所指定属性必须与已存在索引属性相同,否则返回失败。
示例(HEAP 表、单机 TAC 表)
Copied!
# validate|novalidate
指定在定义某个约束项时,是否对表中现有的数据进行该项约束检查,VALIDATE 表示检查,NOVALIDATE 表示不检查。可省略,则默认为 VALIDATE。
对于 UNIQUE/PRIMARY KEY/NOT NULL 约束项,系统将始终默认为 VALIDATE,执行约束检查,即使指定了 NOVALIDATE。
示例(HEAP 表、TAC 表)
Copied!
# enable|disable
指定在定义某个约束项时,是否启用约束,ENABLE 表示启用,DISABLE 表示停用。可省略,则默认为 ENABLE。
在定义 UNIQUE/PRIMARY KEY 约束项并指定 DISABLE 时,系统不会创建对应的索引。
示例(HEAP 表、TAC 表)
Copied!
版权声明: 本文为 InfoQ 作者【YashanDB】的原创文章。
原文链接:【http://xie.infoq.cn/article/92471aaa7356ca0fe077506eb】。文章转载请联系作者。
评论