ALTER TABLE ADD CONSTRAINT 语句可以创建或过滤 NOVALIDATE 方式的外键约束。NOVALIDATE 约束方式防止数据库服务器在创建引用约束时,验证每一行的外键值是否符合被引用表中的主键值。
使用此语法创建启用或过滤 NOVALIDATE 方式的外键约束:
该语法忽略 DISABLED 关键字。因为禁用的约束不会进行违例检查,在这种情况下,NOVALIDATE 关键字不重要。
如果没有列或列表立即跟随在 REFERENCES 关键字之后,则缺省列(或列组)是 pk_tab 表的主键。如果 pk_tab 和 table 或 synonym 指定同一表,则约束自我引用,并没有缺省的主键列。
如果您没有声明约束的名称,则数据库服务器为此新约束生成一个标识符,它注册在 sysconstraints 和 sysobjstate 系统目录表中。
ALTER TABLE ADD CONSTRAINT 语句支持引用约束的 NOVALIDATE 方式作为创建或过滤引用约束时绕过数据完整性检查的机制。
尽管引用约束保护数据完整性,在某些情况下您正要移动到新数据库服务器实例的数据库表是已知的自由参照完整性违规。对于大表上的外键约束,验证约束所需的时间要十分充分。如果有数百万行的表正从 OLTP 环境移动至数据仓库环境,则验证目标环境中的外键可能增加数量级迁移所需的时间。
例如,您可以删除大表上的外键约束,然后在该表迁移到目标表环境之前,立即重新创建 ENABLED NOVALIDATE 方式或 FILTERING NOVALIDATE 方式的约束。重建外键约束的 ALTER TABLE ADD CONSTRAINT 操作的花销几乎很小,因为它绕过了对每一行引用约束的验证。因为 NOVALIDATE 方式不会持续超过创建该约束的 ALTER TABLE 操作,抵达数据仓库环境中的表带有 ENABLED 或 FILTERING 方式的约束,保护了随后 DML 操作中数据的参照完整性。
CREATE TABLE parent(c1 INT, c2 INT, c3 INT); CREATE UNIQUE INDEX idx_parent_c1 ON parent(c1); ALTER TABLE parent ADD CONSTRAINT PRIMARY KEY(c1) CONSTRAINT cons_parent_c1;
以下语句创建了另一个表,名为 child,它的第一列与 parent 表的主键列的数据类型相同,并在 child 表定义主键约束 cons_child_x:
CREATE TABLE child(x1 INT, x2 INT, x3 VARCHAR(32)); ALTER TABLE child ADD CONSTRAINT (FOREIGN KEY(x1) REFERENCES parent(c1) CONSTRAINT cons_child_x1);
假设之后的 DML 操作(未显示)向此 parent 表和 child 表填充数据行。在一些点,此工作流程要求数据从它的 OLTP 产品环境移动到另一个处理业务分析应用程序的数据库中。
ALTER TABLE child DROP CONSTRAINT cons_child_x1;child 表导入到新的环境后,下列语句可以在 child 表上重建一个相同名称的约束,而不用检查每一行的参照完整性违规:
ALTER TABLE child ADD CONSTRAINT (FOREIGN KEY(x1) REFERENCES parent(c1) CONSTRAINT cons_child_x1 NOVALIDATE);ALTER TABLE 语句执行完毕之后,新的 cons_child_x1 引用约束在缺省情况下处于 ENABLED 方式。