唯一性约束(Unique constraint)
唯一性约束可以保护表中多个数据列,保证在保护的数据列中任何两行的数据都不相同。唯一性约束与表一起创建,在唯一性约束创建后,可以使用ALTER TABLE语句修改。
语法:
column_name data_type CONSTRAINT constraint_name UNIQUE |
如果唯一性约束保护多个数据列,那么唯一性约束要作为表约束增加。语法如下:
CONSTRAINT constraint_name (column) UNIQUE USING INDEX TABLESPACE (tablespace_name) STORAGE (stored clause) |
唯一性约束由一个B-tree索引增强,所以可以在USING子串中为索引使用特殊特征,比如表空间或存储参数。CREATE TABLE语句在创建唯一性约束的同时也给目标数据列建立了一个唯一的索引。
CREATE TABLE insured_autos (policy_id NUMBER CONSTRAINT pk_policies PRIMARY KEY, vin VARCHAR2(10), coverage_begin DATE, coverage_term NUMBER, CONSTRAIN unique_auto UNIQUE (policy_id,vin) USING INDEX TABLESPACE index STORAGE (INITIAL 1M NEXT 10M PCTINCREASE 0) ); |
用户可以禁用未以性约束,但他仍然存在,禁用唯一性约束使用ALTER TABLE 语句
ALTER TABLE insured_autos DISABLE CONSTRAIN unique_name; |
删除唯一性约束,使用ALTER TABLE....DROP CONSTRAIN语句
ALTER TABLE insured_autos DROP CONSTRAIN unique_name; |
注意用户不能删除在有外部键指向的表的唯一性约束。这种情况下用户必须首先禁用或删除外部键(foreign key)。
删除或禁用唯一性约束通常同时删除相关联的唯一索引,因而降低了数据库性能。经常删除或禁用唯一性约束有可能导致丢失索引带来的性能错误。要避免这样错误,可以采取下面的步骤:
1、在唯一性约束保护的数据列上创建非唯一性索引。
2、添加唯一性约束
主键(Primary Key)约束
表有唯一的主键约束。表的主键可以保护一个或多个列,主键约束可与NOT NULL约束共同作用于每一数据列。NOT NULL约束和唯一性约束的组合将保证主键唯一地标识每一行。像唯一性约束一样,主键由B-tree索引增强。
创建主键约束使用CREATE TABLE语句与表一起创建,如果表已经创建了,可以使用ALTER TABLE语句。
CREATE TABLE policies (policy_id NUMBER CONSTRAINT pk_policies PRIMARY KEY, holder_name VARCHAR2(40), gender VARCHAR2(1), marital_status VARCHAR2(1), date_of_birth DATE ); |
与唯一性约束一样,如果主键约束保护多个数据列,那么必须作为一个表约束创建。
CREATE TABLE insured_autos (policy_id NUMBER, vin VARCHAR2(40), coverage_begin DATE, coverage_term NUMBER, CONSTRAINT pk_insured_autos PRIMARY KEY (policy_id,vin) USING INDEX TABLESPACE index STORAGE (INITIAL 1M NEXT 10M PCTINCREASE 0) ); |
禁用或删除主键必须与ALTER TABLE 语句一起使用
ALTER TABLE policies DROP PRIMARY KEY; |
或
ALTER TABLE policies DISABLE PRIMARY KEY; |
外部键约束(Foreign key constraint)
外部键约束保护一个或多个数据列,保证每个数据行的数据包含一个或多个null值,或者在保护的数据列上同时拥有主键约束或唯一性约束。引用(主键或唯一性约束)约束可以保护同一个表,也可以保护不同的表。与主键和唯一性约束不同外部键不会隐式建立一个B-tree索引。在处理外部键时,我们常常使用术语父表(parent table)和子表(child table),父表表示被引用主键或唯一性约束的表,子表表示引用主键和唯一性约束的表。
创建外部键使用CREATE TABLE语句,如果表已经建立了,那么使用ALTER TABLE语句。
CREATE TABLE insured_autos (policy_id NUMBER CONSTRAINT policy_fk REFERENCE policies(policy_id ON DELETE CASCADE, vin VARCHAR2(40), coverage_begin DATE, coverage_term NUMBER, make VARCHAR2(30), model VARCHAR(30), year NUMBER, CONSTRAIN auto_fk FROEIGN KEY (make,model,year) REFERENCES automobiles (make,model,year) ON DELETE SET NULL ); |
ON DELETE子串告诉ORACLE如果父纪录(parent record)被删除后,子记录做什么。缺省情况下禁止在子记录还存在的情况下删除父纪录。
外部键和NULL值
在外部键约束保护的数据列中NULL值的处理可能产生不可预料的结果。ORACLE 使用ISO standar Match None规则增强外部键约束。这个规则规定如果任何外部键作用的数据列包含有一个NULL值,那么任何保留该键的数据列在父表中没有匹配值。
比如,在父表AUTOMOBILES中,主键作用于数据列MAKE,MODEL,YEAR上,用户使用的表INSURED_AUTOS有一个外部约束指向AOTOMOBILES,注意在INSURES_AUTOS中有一数据行的MODEL列为NULL值,这一行数据已经通过约束检查,即使MAKE列也没有显示在父表AUTOMOBILES中,如下表:
表1 AUTOMOBILES
MAKE | MODEL | YEAR |
Ford | Taurus | 2000 |
Toyota | Camry | 1999 |
表2 INSURED_AUTOS
POLICY_ID | MAKE | MODEL | YEAR |
576 | Ford | Taurus | 2000 |
577 | Toyota | Camry | 1999 |
578 | Tucker | NULL | 1949 |
延迟约束检验(Deferred Constraint Checking)
约束检验分两种情况,一种是在每一条语句结束后检验数据是否满足约束条件,这种检验称为立即约束检验(immediately checking),另一种是在事务处理完成之后对数据进行检验称之为延迟约束检验。在缺省情况下Oracle约束检验是立即检验(immediately checking),如果不满足约束将先是一条错误信息,但用户可以通过SET CONSTRAINT语句选择延迟约束检验。语法如下:
SET CONSTRAINT constraint_name|ALL DEFEERRED|IMMEDIATE --; |