Concept-第21章翻译

来源:互联网 发布:.9.png制作工具 mac版 编辑:程序博客网 时间:2024/05/13 09:17

21 数据完整性

这篇文章主要解释了如何使用完整性约束来保证数据库遵循商业规则并且防止表中出现无效的数据信息。

主要包括下面的内容:

*数据完整性的介绍

*完整性约束的概述

*完整性约束的类型

*约束检查的机制

*延迟约束检查

*约束状态

 

数据完整性的介绍

数据哭内的数据必须坚持预定义的规则集是非常重要的,这些规则集是由数据哭管理员和应用程序开发者所定义的。数据完整性的一个例子是,考虑表employeesdepartments以及为每张表内的信息所遵循的业务规则。图21-1 中说明如下:

21-1 数据完整性的例子

注意在每张表的一些列都有特定的规则来约束包含在表中的数据。

 

数据完整性的类型

这部分主要描述了能够应用到表中的列的规则来实现数据完整性的不同类型

空规则

一个空规则定义在一个单独的列上,这个规则在那列上是规定了更新或者插入是否允许包含有空(没有值)值。

唯一列值

定义在一列上的唯一值规则只有在该列(或者列的集合)上包含有唯一值的行才被允许插入或者被更新。

唯一键值

定义在键列(一列或者是多列的集合)上的唯一键值规则指定了表中每行数据是被键列上的值唯一的标识。

 

引用完整性规则

一个引用完整性规则是一个定义在一个表中键列(一列或者多列的集合)上的规则,保证在键上的值与一个被引用表上的键值是相匹配的。

引用完整性也包括那些规定哪些数据操纵类型在被引用的值上是允许,以及这些活动是如何影响依赖的值的。这些与引用完整性相关的规则是:

*限制:禁止对引用值的的更新或者删除

*设置NULL:当引用值被更新或者修改时,所有与依赖值相关的值被置为空

*设置默认值:当引用值被更新或者删除时,所有与依赖值相关的值被设置为一个默认值

*串联操作:当引用值被更新时,所有与依赖值相关的值都被相应地更新。当引用行被删除时,所有这些依赖的行也都被删除。

*无操作:禁止引用值更新或者删除。此规则与RESTRICT不同,因为这个规则只在语句结束时检查或者如果约束被延迟则会在事务结束时进行检查。

 

复杂的完整性检查

复杂的完整性检查是一个在一列上用户定义的规则,该规则根据在该列(列的集合)上包含的值来允许或者禁止行的插入,更新或者删除。

 

Oracle是如何强制实现数据完整性的

Oracle使你能够定义或者强制实现前部分所描述的数据完整性规则类型。这些规则的大多数通过使用完整性约束和数据库的触发器来定义的。

 

完整性约束的描述

一个完整性约束是一个为表中列定义规则的显式的方法。Oralce支持下面的完整性约束:

*NOT NULL:该约束是关于列中非空的规则

*UNIQUE;唯一性约束是关于唯一值的规则

*PRIMARY KEY;该约束是关于主键值的规则

*FOREIGN KEY;该约束是关于引用完整性的规则。Oracle支持FOREIGN KEY完整约束的使用来定义引用完整性活动,包括:

  *更新无操作和删除无操作

  *删除串连操作

  *删除置空

*为复杂的完整性规则检查约束

注意:如果孩子表和父表是在分布式数据库上的不同的节点上,就不能够使用显式完整性约束来强制实现引用完整性。但是,在分布式数据库中可以使用数据库触发器来强制实现引用约束。

 

数据库触发器

Oracle也使你能够使用非显式的方式来强制完整性规则,通过使用数据库触发器(是一种数据库存储过程在插入,更新或者删除操作时自动地调用)。

 

完整性约束的概述

Oracle使用完整性约束来防止无效的数据被记录到数据库的基表中。你可以定义完整性约束对数据库中存储的信息遵循你想要进行的业务规则。如果DML语句执行的返回结果的任何一个违反了完整性约束的话,oracle会回滚该语句并且返回一个错误信息。

注意:在视图上的操作(以及表的同义词)是受制于定义在基表上的完整性约束。

比如:假设你为employees表的salary列上定义了完整性约束。这个完整性约束强制实现在该表的salary列上不包含数字值大于10000的行记录的规则。如果一个插入或者更新语句试图违反这个完整性约束的话,那么oracle会回滚该语句并且返回一个错误消息的信息。

oracle中执行的完整性约束符合 ANSI X3.135-1989 ISO 9075-1989 标准。

 

完整性约束的优势

这部分描述了完整性约束与其他解决方案相比的的一些优点,这些优势包括:

*强制在数据库应用程序的代码中实现业务规则

*使用存储过程来完全控制对数据的访问

*使用触发的数据库存储过程来强制实现业务规则

 

声明即用

使用SQL语句来定义完整性约束。当你定义或者修改一张表,不需要额外的编写程序。SQL语句比编写程序代码要容易,并且不会出现程序错误。Oracle控制他们的函数。由于这些原因,声明的完整性约束与编写代码和数据库触发器要容易的多。声明方法比使用存储过程要好是因为存储过程对数据完整性的解决方案控制了数据访问,但是完整性约束不会阻碍即席数据访问的灵活性。

集中化的规则

对于表(而不是应用程序)定义完整性约束,并且将完整性约束存储在数据字典中。任何由应用程序所输入的数据必须遵循相关数据表上的完整性约束。通过将业务规则从应用程序代码中移动到集中化的完整性约束中,数据库中的表被保证包含有效的数据,不管是哪些数据库应用程序操纵数据信息。存储过程不能提供与存储在表中的集中化的规则一样的优势。数据库触发器能够具有此优势,但是其执行的复杂性要远大于声明使用完整性约束的方式。

 

应用程序开发生产力最大化

如果业务规则通过完整性约束来强制实现变更,那么管理员只需要变更完整性约束日,然后所有的应用程序自动地遵循被修改的约束。相反,如果业务规则是通过每个数据库应用程序来强制实现的话,那么开发者将要必须修改所有的应用程序代码并且重新编译,调试,以及测试被修改的应用程序。

 

及时的用户反馈

Oracle在数据字典中存储关于每个完整性约束的特定的信息。你可以设计数据库应用程序使用这些信息来及时地将有关完整性约束违背的的信息反馈给用户。这种反馈是在oracle运行以及检查SQL语句之前。比如:一个oracle窗体应用程序可以使用存储在数据字典中的完整性约束定义,在值被记录到窗体中时,使用约束来检查是否存在违反约束的情况,这种检查是在应用程序提交该语句之前进行。

 

性能优势

完整性约束声明的语法是被明确地定义,并且为每个特定的声明原则都进行了性能优化。Oracle优化器能够使用声明信息来了解更多关于数据的情况,来改进整体的查询性能。(也,将完整性约束从数据库应用程序代码和数据库触发器中拿出来来保证只有在当需要的时候来执行检查)

数据加载的灵活性和违反完整性约束的识别

你可以临时地禁用完整性约束以便大量数据被加载而不需要进行约束检查。当数据加载结束时,你可以很容易地启用完整性约束,并且能够自动地将任何违反完整性约束的新的数据行报告到一张单独的异常表中去。

 

完整性约束的性能

强制使用数据完整性约束也需要在性能上有一些损失。一般来讲,完整性约束所造成的性能上的损失最多和执行SQL语句时所进行的约束检查造成的性能上损失是一样的。

 

完整性约束的类型

你可以使用下面的完整性约束来对列值的输入强加限制:

*NOT NULL完整性约束

*唯一键的完整性约束

*主键的完整性约束

*引用完整性约束

*检查完整性约束

 

NOT NULL完整性约束

默认情况下,表中的所有列允许空值。NULL意味着没有值。一个NOT NULL约束需要表中的列包含非空值。比如:你可以对employees表中的每行的last_name列定义一个NOT NULL约束,要求该列上必须有一个值输入。

21-2 说明一个 NOT NULL完整性约束

 

唯一性完整性约束

一个唯一性完整性约束需要列或者列的集合上的每个值必须唯一----也就是说在执行的列或者列的集合上不允许有重复的行记录存在。

比如:在图21-3 中在表dept上的DNAME列上定义了唯一性约束防止有重复的部分名字的行记录存在。

 

唯一键

定义唯一键约束中包含的列被称为唯一键。唯一键经常被错误得认为是唯一键约束或者是唯一索引术语的同义词。但是,应该注意键只是在完整性约束定义中所使用的列或者是列的集合。

如果唯一键是由多列组成的话,那么该列组被称为符合唯一键。比如:图21-4 customer表有一个定义在复合唯一键(area phone 列)上的唯一键约束。

21-4 复合的唯一键约束

唯一键约束允许你可以输入区域编码和电话号码任意多次,但是输入的区域编码和电话号码的组合在表中是不允许重复的。这样就消除了电话号码的无意重复。

 

唯一键约束和唯一索引

Oracle使用索引强制实现唯一完整性约束。比如:图21-4 oracle通过隐式地在复合唯一键上创建一个唯一索引强制实现唯一键约束。因此,复合的唯一键约束有同样的限制强加在复合的索引上:组成复合唯一键的列的个数最多可达32列。

注意:如果兼容性是设置为oracle 9i或者是更高版本,一个键值的容量(以字节为单位)几乎可以和一个数据块的容量相当。在以前的版本中,键的容量不能够超过相关数据块容量的一半。

如果在当唯一键约束被创建时已经有一个唯一索引存在,那么约束使用已经存在的索引而不再隐式地创建一个新的索引。

 

组合唯一键和NOT NULL完整性约束

在图21-3 和图21-4中,唯一键约束是允许输入NULL值的除非对于该列你也定义了NOT NULL约束。事实上,任何包含没有定义NOT NULL约束的列行记录可以包括NULL值,因为NULL值被认为不等于任何值。在一个列(或者复合唯一键上的所有列)上的空值总是满足唯一性约束。

使用唯一键和NOT NULL完整性约束的组合的列是很常见的。这种组合强制用户在唯一键上输入值并且也确保了任何新插入的行记录不会与已经存在的行记录的数据相重复。

注意:因为唯一性约束的查询机制是建立在多列上,所以在复合唯一键约束的键中,如果部分列为空,其他不为空的列也不能够有相同的值。

 

主键完整性约束

在数据库中的每张表至多有一个主键约束。受制于次约束的列(一列或者多列)的值可以作为一行数据的唯一标识。即每行数据是由此主键命名。

Oralce实现的主键的完整性约束可以保证数据遵循下面的原则:

*在主键指定的列或者多列中的值不存在有重复的;

*主键的列上不允许为空。也就是说对于每行的主键列上都必须有值存在。

 

主键

包含在表中主键完整性约束中的列被称为主键。尽管主键不是必须需要的,但是每张表有一个主键以便:

*在表中的每行记录能够被唯一的标识;

*在表中没有重复的行记录

21-5 一个主键约束

 

主键约束和索引

Oracle使用索引强制实现所有主键的约束。在图21-5 中,为deptno列创建的主键约束,实现方式是采用隐式的创建索引的方式来创建的:

*在该列上创建一个唯一性索引

*为该列定义NOT NULL约束

复合的主键约束限制最多有32列,对于复合索引也具有同样的限制。索引的名字和约束的名字一样。你可以为通过在用来创建约束的CREATE TABLE或者ALTER TABLE 语句中包含ENBALE语句来为索引定义存储选项。如果当主键约束被创建时以存在一个唯一性的索引存在,那么主键约束使用该索引而不是创建一个新的索引。

 

引用完整性约束

在关系数据库中不同的表可以依据共同的列建立关联关系,并且管理列关系的原则必须被维护。引用完整性原则保证这些关系被维护。

下面的术语是与引用完整性约束有关的:

术语

定义

外键

包含在引用完整性约束中的列或者列的集合引用了一个被引用的键

引用键

被外键所引用的相同表或者不同表的唯一键或者主键

依赖的或者孩子表

包含外键的表。因此,这是一张依赖被引用的唯一或者主键的值的表

引用或者父表

被孩子表的外键所引用的表。此表的引用键决定了孩子表中是否允许特定的插入或者更新操作

引用完整性约束要求子表中的每一行的外键中的值必须和与父表中的一个值相匹配。

 

21-6 显示了在emp表中的deptno列上定义的外键。该外键保证了在该列上的每个值必须与dept表中的主键中的值相匹配。因此,在emp表中deptno列上不会出现错误的部门号。

外键可以定义在多列上。但是,复合的外键必须引用复合的并且使用相同数量的列并且相同类型的列的主键或者唯一键。因为复合的主键和唯一键限制最多可达32列,一个复合的外键也最多可达32列。

21-6 引用完整性约束

自引用完整性约束

另一种类型的引用完整性约束,在图21-7中,被称为自引用完整性约束。这种类型的外键与其引用的父键在同一张表中。

21-7 ,引用完整性约束确保在emp表中的mgr列上的每个值对应与在同一张表中的empno列上当前存在的值,但是,并不需要在同一行,因为每个经理也必定是一个员工。完整性约束消除了在mgr列上错误员工号的可能性。

21-7 单表引用完整性约束

 

空和外键

关系性模型允许外键的值或者匹配被引用的键或者匹配唯一键的值,或者是空。如果一个复合外键的任何一列为空,那么该复合键中非空的部分不需要匹配父键的任何相应的部分。

 

引用完整性约束所定义的活动

如果被引用父键的值被修改的话,那么引用完整性约束可以对孩子表中的依赖行执行一些特殊的活动。被oracle的外键完整性约束所支持的引用活动包括:UPDATE ,DELETE NO ACTION以及DELETE CASCADE

注意:其他不被oracle的外键完整性约束所支持的引用活动能够使用数据库触发器来强制实现。

 

禁止操作

禁止操作选项是指如果对引用键值(referenced key value)的更新或删除操作返回的数据会将破坏引用完整性约束,则此操作不能执行。比如:如果一个主键值被外键值所引用的话,那么被引用主键值将不能被删除因为有依赖的数据存在。

 

串联删除

串联删除是指当包含被引用的键值的行被删除之后,会引起孩子表中带有依赖的外键值的所有记录也同时被删除。比如:如果父表中一行记录被删除,并且在孩子表中被一个或者多个外键值存在引用该行的主键值的记录存在,那么在孩子表中的所有引用主键值的行记录也从孩子表中删除。

 

置空

置空是指当包含引用键的行记录被删除的话,会引起孩子表中带有依赖的外键值的所有记录中的该值设置为空值。比如:如果employee_id引用tmp表中的manager_id列,然后删除一个经理会引起所有为该经理工作的员工的mamager_id设置为空值。

 

各引用操作对DML的限制

21-1 列出了在父表中的主键和唯一键值以及孩子表中的外键值上的不同的引用操作所允许的DML语句。

21-1 各引用操作对 DML 的限制

DML语句

对父表执行

对子表执行

INSERT

如果父键值唯一时允许执行

只有在外键值在父键中存在或者部分或全部为空时允许执行

UPDATE No Action

如果更新操作没有使孩子表中任何记录没有引用父键值,则允许执行

如果新的外键值还是引用了被引用的键值。

DELETE NO ACTION

如果在孩子表中没有引用此主键值则允许执行

总是允许执行

DELETE CASCADE

总是允许执行

总是允许执行

DELETE SET NULL

总是允许执行

总是允许执行

 

并发控制,索引,和外键

大多数,用户需要在外键上创建索引。只有当所匹配的唯一键或者主键从来没有被更新过或者删除,这种情况下不需要在外键上创建索引。

Oracle使对父键和依赖键外键的关系的并发控制最佳化。你可以控制采用什么并发控制机制来维护这些关系,并且依据不同的情况来选择并发控制机制,这样可以带来很大的益处。下面部分解释了可能的情况以及为每种情况推荐使用哪种并发控制机制。

 

外键上无索引

21-8 说明了在当在外键上没有定义索引以及当在父表中的行记录被更新或者删除时oracle所使用的锁机制。向父表中插入数据不需要对子表加任何锁。

没有索引的外键使得在该主键上的DML操作获取到一个在外键表上的共享行排它表锁(有时候也被称为share-subexclusive table lock, SSX)。这样就防止其他事务对该表进行DML操作。SSX锁在被获取之后就立即被释放了。如果有多个主键被更新或者删除的话,对每行执行的DML操作都需要对子表进行一次加锁和解锁的操作。

注意:在外键上创建索引只能引起一个行共享表锁(也被称为subshare table lock, SS)。这样就会防止其他事务对子表加排它表锁,但是行共享表锁不会阻塞其他事务对父表或者子表的DML操作。

21-8 当在外键上没有定义索引时的锁机制

 

在外键上创建索引

21-9 说明当在外键上定义了索引,并且有新的行记录被插入,更新或者在子表中的记录被删除时所使用的锁机制。

在外键上创建索引会给子表加共享表锁(也被称为subshare table lock, SS)。这样会防止其他事务给子表加排它表锁,但是该SS锁不会阻塞其他事务对父表或者子表进行DML操作。

当更新活动发生在子表中的时候如果此时有对父表的任何更新或者删除操作,这样情形适合采用本节所讲的锁机制。对父表的插入,更新,以及删除不需要对子表加任何锁,尽管更新以及删除将会等待在子表上的索引的行级锁释放。

21-9 当外键上定义了索引的锁机制

如果孩子表定义了ON DELETE CASCADE,那么删除父表中的记录会导致子表中的记录的删除。在这种情况下,oracle采用锁机制与手工的删除父表记录的操作之后,再删除子表中的相应记录时采用的锁机制是一样的。

 

CHECK完整性约束

定义在一列或者多列上的CHECK完整性约束需要表中的数据行满足用户定义的条件或者条件判断结果为不确定。如果一个DML语句使CHECK完整性约束的判断结果是FALESE的话,那么该语句被回滚。

 

检查条件

检查约束让你通过定义检查条件来强制实现特定的完整性原则。检查约束的条件有一些限制:

*检查条件需要在用于被插入或者被更新的行记录的值必须是一个表达式;

*检查条件不包含一个子查询;序列;SYSDATEUIDUSER,或者USERENVSQL函数;或者LEVEL或者ROWNUM虚列;

在评估那些包含字符串或者包含全球化支持参数SQL函数的检查约束时,oracle使用默认的数据库全球化支持设置。你可以通过显式地定义全球化支持参数,含有自定义的函数的检查约束来覆盖默认的设置。

 

多重检查约束

一个单独的列可以在多重检查约束的定义中所引用。在该列上对检查约束的数量没有限制。

如果你对一列创建多重约束,仔细地设计这些检查约束以便这些约束不相冲突。Oracle对条件的检查是不会有特定的顺序。Oracle也不会验证检查约束是不相互排斥的。

 

约束检查机制

为了了解当约束出现时哪种类型的活动允许执行,理解oracle什么时候实际地执行约束检查是非常有用的。假设下面的情景:

*象图21-7 中已经被定义的EMP

*自身引用约束使在mgr列上的项依赖在empno列上的值。为了简单化,下面部分讨论只针对emp表中的empnomgr列来讨论。

考虑在EMP表上第一行记录的插入。此时在EMP表上没有行记录,所以如果mgr列上需要引用任何存在的empno列上的值,那么该行记录该如何被插入?三种做的可能性如下:

*假设mgr列上没有一个NOT NULL约束定义在其上,那么对于第一行记录上的mgr列的值可以输入null值。因为在外键上允许null值,所以该行能够被成功的插入到表中;

*如果第一行记录上的mgr列和empno列上的值是一样的。在这种情况下显示出在语句在被运行完之后oracle才进行约束检查。为了允许那些在父表和外键上的值是相同的记录也能够被插入,oracle必须首先运行语句(也就是插入新的行记录),并且然后检查看在表中的任何行是否有一个empno的值正好对应于新行的mgr列上的值。

*对于多行插入语句,比如带有select语句的INSERT语句,能够插入那些相互有应用关系的行。比如:第一行的empno列可能为200并且mgr300,同时第二行上可能empno上为300mgr列上为200

 

在这种场景中需要考虑相同的自身引用的完整性约束。公司已经被收购。因为公司被收购,该公司的所有的员工号必须被更新为在当前的值上加5000来和新公司的员工号相协调。因为经理的员工号也是真正的员工号,这些也必须加5000。(见图21-10

21-10 在更新前的EMP

Update employees

  Set  employee_id=employee_id +5000,

       Manager_id=mamnager_id +5000;

 

尽管有一个约束定义来验证每个mgr列上的值必须匹配empno列上的值,但由于oracle是在语句执行完之后才会运行约束检查。图21-11 显示了在任何约束被检查之前oracle运行整个SQL语句的活动。

21-11 约束检查

这部分说明了在INSERTUPDATE语句执行期间的约束检查机制。对于所有DML语句类型都采用这种相同的约束检查机制,包括UPDATEINSERT,以及DELETE语句。

 

该例子使用自身引用的完整性约束来说明了约束检查机制。相同的机制也被用于各种类型的约束,包括:

*NOT NULL

*UNIQUE 键值

* PRIMARY KEY

*FOREIGN KEY约束的各种类型

*检查约束

 

默认的列值和完整性约束检查

默认的值在语句被解析之前被包含在INSERT语句中作为其一部分。因此,默认的列值也需要进行所有完整性检查。

 

延迟约束检查

你可以将约束检查延迟到事务结束之后。

*如果系统约束检查是发生在事务提交时称该检查为延迟约束检查。如果违反了延迟约束,该提交操作将会导致事务被回滚;

*如果约束检查是立即进行的(没有延迟),那么约束是在每个语句的结束之后进行检查。如果违反了约束,那么语句被立即被回滚。

如果约束引起一个活动(比如:串连删除),这些活动将作为引起该活动的语句的一部分,不管该约束是延迟的还是立即的。

 

约束属性

你可以定义约束或者是可延迟的或者是不可延迟的,以及或者是初始延迟的,或者是初始立即的。这些属性对于每个约束来说是不同的。你可以在CONSTRAINT语句中定义关键字来指定:

*DEFERABLE 或者NOT DEFERRABLE

*INITIALLY DEFERRABLE 或者INITIALLY IMMEDIATE

约束能够被添加,删除,启用,禁用或者验证。你有可以修改一个约束的属性。

 

设置约束模式

SET CONSTRAINTS语句使对一个特殊的事务的约束设置为或者是DEFERRED或者是IMMEDIATE(此语句在语法及语义上均符合 ANSI SQL92 标准)。你可以使用这个语句来为一系列约束名或者为所有的约束设置约束模式。

SET CONSTRAINTS模式在事务期间一直起作用知道另外一个SET CONSTRAINTS语句重新设置其模式。

SET CONSTRAINTS…IMMEDIATE语句会使指定的约束在每个约束语句执行之后立即被检查。Oracle首先检查在事务中的之前被延迟的约束,然后继续对该事务中任何新的语句进行立即约束检查,直到所有被检查的约束是一致的并且没有执行其他的SET CONSTRAINTS语句。如果任何约束检查失败,就会产生一个错误。在这个时间点上,一个提交操作会引起整个事务回滚。

 

ALTER SESSION语句也有SET CONSTRAINTS IMMEDIATE或者DEFERRED的语句。此语句暗示设置所有事务的可延迟的约束(也就是,你不能定义一系列的约束名称)。这些语句等价于在当前会话中的每个事务的开始设置SET CONSTRAINTS语句。

在事务结束设置立即约束检查,这样可以检查事务提交是否成功。你可以在一个事务中的最后一个语句执行时通过设置约束为IMMEDIATE来避免意外的回滚。如果有任何约束检查失败的话,你可以在事务提交之前纠正错误。

SET CONSTRAINTS在触发器中是不允许使用的。

SET CONSTRAINTS能够在分布式中使用。当用户执行 SET CONSTRAINTS ALL 语句时,那些有事务在进行中的存在的数据库连接(LINK)将会被通知,并且新的链接在开始的事务的时候也被通知。

 

唯一约束和索引

当用户的事务产生数据不一致时,用户可以看到不一致数据的约束。你可以在物化视图上可以设置延迟唯一约束和外键约束,来使物化视图可以快速,完全的更新。

延迟唯一性约束总是使用非唯一性索引。当你迁移一个延迟约束时,它的索引是保留的。这样是方便的是因为在你禁用一个约束时存储信息仍然是可以获取得到的。如果非唯一性索引在约束被强制实现之前就被放置在键列上,非延迟唯一性约束和主键也使用非唯一性索引。

 

约束状态

*ENBALE确保所有输入的数据是都遵从约束的

*DISBALE允许输入数据,不管这些数据是否遵从约束

*VALIDATE确保存在的数据是遵从约束的

*NOVALIDATE意味着一些存在的数据可能不遵从约束

 

此外:

*ENABLE VALIDATE的功能是和ENABLE一样的。约束被检查并且保证所有的行记录都遵从这些约束

*ENABLE NOVALIDATE意味着约束是被检查的。但是并不一定需要所有的行记录都遵从这些约束。这种允许存在的数据可以违反约束,同时确保那些新的数据或者被修改的数据是有效的;

ALTER TABLE语句中,ENABLE NOVALIDATE可以不需要对表中存在的数据进行验证检查而可以对禁用的约束进行恢复。

*DISABLE NOVALIDATE 是和DISABLE是相同的。这种约束不被检查并且也不保证所有数据都遵从约束

* DISABLE VALIDATE是禁用约束,删除在约束上的索引,并且不允许在被约束列上的任何修改。

对于唯一性约束,DISABLE VALIDATE状态使你能够使用ALTER TABLE语句中的EXCHANGE PARTITION语句从非分区的表中向分区表中加载数据。

在这些状态之间的转换被下面的原则所管理:

*ENABLE隐含着VALIDATE,除非NOVALIDATE被指定;

*DISABLE隐含着NOVALIDATE,除非VALIADATE被指定

*VALIDATENOVALIDATE默认不隐含任何ENABLE DISABLE

*当唯一键或者主键从DISABLE状态移动到ENABLE状态时,如果没有索引存在,唯一性索引将被自动创建。同样,当唯一键和主键从ENABLE状态转换到DISABLE状态并且键上有唯一索引,那么唯一索引将被删除。

*当任何约束的状态从NOVALIDATE转换为VALIDATE状态时,所有数据必须被检查。(这个会非常地慢。)但是,状态从VALIDATE转换到NOVALIDATE只是简单的将数据已经被检查过这个事实忘记。

*将一个单独的约束从ENBALE NOVALIDATE状态转换为ENABLE VALIDATE状态不会阻塞数据块的读,写,或者其他DDL语句。它可以并行地被执行。

 

约束状态修改

你可以使用ALTER TABLE MODIFY CONSTRAINT语句来修改下面的约束状态:

*DEFERRABLE 或者NOT DEFERRABLE

*INITALLY DEFERRED 或者INITALLY IMMEDIATE

*RELY或者NORELY

*USING INDEX….

*ENABLE或者DISABLE

*VALIDATE 或者NOVALIDATE

*EXCEPTIONS INTO…