当在引用的表上存在索引时启用外键约束
在缺省情况下,当它们的模式更改为 ENABLED 时,数据库服务器自动地验证引用的约束。当 SET CONSTRAINTS 语句启用外键约束时,您可能节省时间,如果该引用的表在对应于外键约束的键的列上(或列的集合上)已有唯一索引或主键约束的话。
关于如何验证启用的外键约束,数据库服务器作出基于成本的决策。在许多上下文中,索引键算法可能更快,因为它通过仅扫描索引值,而不是索引表中所有的行来验证该约束。
数据库服务器可考虑使用索引键算法来验证它启用的外键约束,但当 SET CONSTRAINTS ENABLED 语句重置该约束模式时,仅当满足所有下列条件时才行:
SET CONSTRAINTS 语句仅正在启用一个外键约束。
如果是这种情况,则数据库服务器仅需要检查在其上正在启用外键约束的列上的个别值。同时验证两个外键约束可能会需要在同一扫描上使用两个索引,这是不支持的。
同一语句没有启用 CHECK 约束。
如果 SET CONSTRAINTS 语句正在启用多个约束,则验证 CHECK 约束会要求检查每行,而不是个别的值。在那种情况下,不可为了验证外键约束而使用索引键算法。
外键列不包括用户定义的数据类型(UDT)或内建的 opaque 数据类型。
要使得快速的索引键算法尽可能高效,它消除与用户定义的或内建的 opaque 数据类型相关联的所有执行例程的低效率,诸如 BOOLEAN 和 LVARCHAR 内建 opaque 类型。
外键约束的新模式不是 DISABLED。
如果它是启用的,则不需要约束检查算法,因为不会发生对引用的完整性违反的检查。
该表不与活动的违反表相关联。
在检查的时刻,违反表要求必须将不满足新约束的每行插入到违反表内。对每行进行违反扫描会防止数据库服务器使用跳过重复的行的更快的索引键算法。
除了在一个或多个违反行的情况之外,当不满足这些要求时,SET CONSTRAINTS 语句可启用并验证外键约束,但数据库服务器不会考虑使用索引键算法来验证外键约束。扫描整个表导致的附加验证成本通常与表的大小是成比例的。对于非常大的表,这些成本可非常可观。
当您启用自引用外键约束时,其 REFERENCING 子句指定在其上定义约束的同一表,数据库服务器可考虑索引键算法来验证引用的完整性,如果满足以上罗列的所有条件的话。
触发器和重复的索引的模式
您可指定触发器或重复的索引的模式。
触发器和重复的索引的模式
当您创建索引或触发器时,或在后续的 SET Database Object Mode 语句中未指定它的模式,在缺省情况下启用该对象。
数据库对象模式的定义
您可使用数据库对象模式来控制 INSERT、DELETE 和 UPDATE 语句的作用。您对模式的选择会影响您正在操作其数据的表、在那些表上定义的数据库对象的行为,以及数据操纵语句自身的行为。
启用的模式
在表上的 DML 操作期间,处于启用的模式的数据库对象充当约束、索引或触发器。
如果当创建约束、索引或触发器时,您未指定数据库对象模式,则缺省地启用它们。数据定义语句 CREATE TABLE、ALTER TABLE、CREATE INDEX 和 CREATE TRIGGER 都以启用的模式创建数据库对象,除非您显式地指定一种不同的模式。
在创建时刻哪种非缺省的对象模式是可用的,依赖于对象的类型:
当创建触发器或非唯一索引时,可替代启用的模式的唯一关键字是 DISABLED。
当创建约束或唯一索引时,替代缺省的或显式的 ENABLED 关键字的包括 DISABLED、FILTERING WITH ERROR 和 FILTERING WITHOUT ERROR。(但如果您仅指定 FILTERING,则对于 FILTERING 对象,FILTERING WITHOUT ERROR 是缺省的错误模式。)
然而,在 ALTER TABLE ADD CONSTRAINT 语句正在创建外键约束时,任何这三种模式都可被替代地指定作为对启用的模式的附加的替代:
oENABLED NOVALIDATE
oFILTERING WITH ERROR NOVALIDATE
oFILTERING WITHOUT ERROR NOVALIDATE。
然而,当 SET Database Object Mode 语句更改现有的约束、索引或触发器的模式时,没有缺省的模式。如果您未指定对象模式,则 SET Database Object Mode 语句失败并报警 -201。如果您想要将约束、索引或触发器的模式从某些其他模式重置为启用的,则必须显式地指定 ENABLED 关键字。
当成功地启用数据库对象时,数据库服务器在系统目录的 sysobjstate 表中注册那个对象状态,并当它的表是后续的 INSERT、DELETE、MERGE 或 UPDATE 语句(或对于 Select 触发器,SELECT 语句)的目标时会考虑那个数据库对象。因此,启动的约束是强制的,启动的索引被更新,且当触发器事件发生时,执行表上的启用的触发器。
例如,在您将外键约束和唯一索引设置为启用的模式之后,当 INSERT、DELETE、MERGE 或 UPDATE 操作尝试违反该表的引用完整性时,数据操纵操作失败,表中的行不被更改,且数据库服务器返回错误消息。
外键约束的 ENABLED NOVALIDATE 模式
在 SET Database Object Mode 语句正在将外键约束的模式更改为 ENABLED 时,数据库服务器通过检测受约束的表中的每一行验证该约束,来核实带有相应的值的行存在于被引用的表的主键列中。此验证可需要大量的时间和资源。您可在 SET Database Object 模式操作期间替代地绕过对违反行的搜索,通过包括 NOVALIDATE 关键字来将外键约束模式更改为 ENABLED NOVALIDATE。对于大型表,指定 ENABLED NOVALIDATE 可显著地减少启用外键约束所需要的时间。
在 SET Database Object Mode 语句的 SET CONSTRAINTS 选项成功地启用外键约束之后,
在 sysobjstate 系统目录表中,该约束模式成功地注册为启用的(E),
在 SET CONSTRAINTS 语句运行时,NOVALIDATE 关键字已阻止了对引用完整性违反的检查,但在系统目录内无处对该关键字编码,且它对外键约束的对象模式或行为没有进一步的影响。
直到删除或禁用那个约束之前,在对它的表执行后续的 DML 操作期间,它都是强制的,以便于维护数据库的引用完整性。