整理自《OCP认证指南》
001 概述
表约束是数据库能够实施业务规则以及保证数据遵循实体——关系模型的一种手段,其中,实体——关系模型由定义应用程序数据结构的系统分析所确定。
在针对定义了约束的表执行任何DML时,如果DML违反了约束,则将自动回滚整个语句。注意,如果一个DML语句影响到多个行,那么,在特定行遇到约束问题前,此语句可能已经局部成功。如果此语句是多语句事务的一部分,那么,事务中已经成功语句将保持完好,但不提交。
考点:如果违反约束,将自动回滚出现问题的整个语句,而不是语句中的单个操作,也不是整个事务。
002 约束类型
Oracle数据库支持的约束类型如下:
·unique
·not Null
·primary key
·foreign key
·check
约束具有名称。最好使用标准命名约定指定名称,如果未显式指定名称,Oracle将为其生成名称。
003 unique约束
unique约束要求,对于列或列组合而言,表中每行的值必须是不同的。如果此约束针对单个列,则相应的列称为键(key)列。如果约束由多列组成(称为组合键唯一约束),这些列并不必是相同的数据类 型,也不必在表定义中互相邻近。
unique约束的怪异之处在于,可以在键列中输入Null值。在键列中,可能有任意数量的包含Null值的行。因此,如果不搜索Null,则可以确保在键列上选择时将仅返回一行;如果搜索Null,那么,键列为Null的所有行都将返回。
考点:对于具有unique约束的列,可以插入多个包含Null的行,而对于包含primary key约束的列而言,则不存在这种可能性。
unique约束通过索引来实施。在定义unique约束时,Oracle将查看键列上的索引,如果不存在,就创建一个。此后,每次插入行时,Oracle都将查看索引,了解键列的值是否已经存在。如果已存在,则将拒绝插入。这些索引(称为B*树索引)的结构不包含Null值,正因为如此,才允许出现多个包含Null的行:索引中根本不存在Null。虽然索引的第一要务是实施约束,但也有次生效应:如果在SQL语句的where子句中使用键列,性能将会提高。但是,选择where key_column IS Null则不使用索引(因为它不包括Null),因此总是导致扫描整个表。
004 NOT Null约束
not Null约束强制在键列中输入值。它针对每个列进行定义,有时被称为强制列(mandatory column)。如果业务要求一组列都具有值,则不能为整个组定义not Null约束 ,而必须针对每列定义not Null约束。
如果尝试插入没有为具有not Null约束的列指定值的行,将导致错误。不懂?????
005 primary key约束
主键(primary key)定位表中单个行的方式。关系数据库范例要求每个表都必须有主键,主键是用于区分每行的列或列组合。Oracle数据库的定义与此范例有所不同,它允许存在不包含主键的表。
主键约束的实现实际上是unique和not Null约束的组合。键列必须具有唯一值,而且不得为空。与unique约束一样,约束列上必须存在索引。如果不存在,将在定义约束时创建索引。一个表只能有一个主键,试着创建第二个,将出现错误。但是,表可以有任意数量的unique和not Null约束列。
考点:unique和primary key约束需要索引。如果不存在,就会自动予以创建。
006 foreign key约束
在父子关系的子表中定义foreign key约束。此约束使子表中的列(或列组合)对应父表的主键列。这些列不必同名,但数据类型必须相同。foreign key约束定义数据库的关系结构:连接第三范式的表的多对一关系。
如果父表具有unique和/或primary key约束,则这些列可用作foreign key约束的基础,即使允许使用Null值,也是如此。
考点:外键约束在子表上定义,但此时的父表上必须存在unique或primary key约束。
unique约束允许约束列中出现Null值,foreign key约束也同样如此。即使父表的行中不存在Null,也可以将行插入到包含Null外键列的子表中。这会创建孤行,并产生令人不快的混乱。一般而言,unique约束中的所有列以及foreign key约束中的所有列最好也定义not Null约束,这往往是业务要求。
尝试在子表中插入父表中没有匹配行的行,将生成错误。同样,如果父表中的某行在子表中已有引用它的行,则删除相应的行将引发错误。可以使用两种技术来更改此行为。首先,可将此约束创建为on delete cascade。这意味着,如果删除父表中的行,那么Oracle将在子表中搜索所有匹配行,并删除它们。这将自动发生。一个较温和的技术是将约束创建为on delete set null。在此情况下,如果删除父表中的行,Oracle将在子表中搜索所有的匹配行,并将外键列设为空。这意味着,子行将称为孤行,但依然存在。如果子表中的列也有not Null约束,则父表上的删除操作将失败。
即使子表中没有行,也不能删除或截断外键关系中的父表。如果使用on delete set Null或on delete cascade子句,这依然适用。
foreign key约束的一个变体是自引用foreign key约束。这将定义一个条件,其中的父行和子行存在于同一个表中。
007 check约束
check约束可用来实施简单规则,如列中输入的值必须在一个值域内。规则必须是一个结构为true或false的表达式。规则可以引用作为字面值输入的绝对值,也可以引用同一行中的其它列,也可以使用一些函数。可以根据需要为一个列应用足够多的check约束,但无法使用子查询来计算值是否被允许,也无法使用诸如sysdate等函数。
提示:not Null约束实际上作为预配置check约束实现。