你的位置:首页 > 数据库

[数据库]Oracle数据库对象_约束


约束是加在表上的一种强制性的规则,是保证数据完整性的一种重要手段。

当向表中插入数据,或修改表中的数据时,必须满足约束所规定的条件。

在设计表的结构时,应该充分考虑在表上需要施加的约束。
保证数据完整性的方法大致有三种,即应用程序代码、触发器和约束。

其中约束是一种更为灵活的方式,它不仅维护更加方便,而且性能也比较高,是保证数据完整性的最佳选择。
约束可以在创建表时指定,也可以在表创建之后再指定

如果在表创建之后再指定约束,可能会因为表中已经存在一些数据不满足这个条件而使得约束无法施加。

约束的类型

在表上可以施加以下五种约束:
NOT NULL 非空约束
UNIQUE 唯一性约束
PRIMARY KEY 主键约束
FOREIFN KEY 外键约束
CHECK 检查约束
NOT NULL约束规定一个列上的值不能为空。

当使用INSERT语句向表中插入一行数据,或者使用UPDATE语句修改一行数据时,必须为该列指定值,不能使其为空。
UNIQUE约束规定一个列上的数据必须唯一,不能有重复值,但是允许为空值。

PRIMARY KEY约束是主键约束。

CREATE TABLE test (
empno NUMBER PRIMARY KEY,
ename VARCHAR2(10) NOT NULL,
job VARCHAR2(9) UNIQUE,
sal NUMBER CHECK(sal>0),
deptno NUMBER REFERENCES dept
);

注:

主键用来唯一地标识表中的一行数据,它规定在主键列上的数据不能重复,并且不能为空。
每个设计合理的表都应该有一个主键。主键可以是一个列,也可以是多个列的组合。
如果在某个列上指定了主键约束,那么就不需要在该列上再指定NOTNULL 约束和UNIQUE约束了。

在一个表上只能创建一个主键。

当创建主键时,在主键列上将自动建立一个唯一性索引,索引的名字与约束的名字相同。
FOREIFN KEY为外键约束。

外键用来与另一个表建立关联关系。

两个表之间的关联关系是通过主键和外键来维持的。
外键规定该列中的数据必须是另一个与之关联的表中的主键列中的数据。
外键可以是一个列,也可以是多个列的组合。

在一个表中只能有一个主键,但是可以有多个外键。

检查约束是一个关系表达式,它规定了一个列必须满足的条件。

注:主键约束和外键约束都会隐式的创建唯一性索引,索引名称与约束名称相同。

反之,创建唯一性索引时,也会隐式的创建唯一性约束。

如何在创建表时指定约束

如果与表同时创建,那么在创建表的CREATE语句中通过CONSTRAINT关键字指定约束的名称约束类型
同时创建表和约束的CREATE语句格式为:

CREATE TABLE 表名(
列1 数据类型CONSTRAINT 约束名1 约束类型,
列2 数据类型CONSTRAINT 约束名2 约束类型,
...

);

其中约束名是为约束指定的唯一的名称。

约束名可以由用户自己指定,也可以自动产生。

如果省略关键字CONSTRAINT和约束名称,那么约束名称将自动产生。

如果约束名称是自动产生的,那么根据这样的名称无法判断约束所在的表以及约束类型。
如果用户自己指定约束名称,则可以在名称中包含表名、约束类型等有用信息。
如果在一个列的定义之后指定该列上的约束时,这种定义约束的方法称为列级约束

约束可以在每个列的定义之后分别指定,也可以在所有列的定义之后一起指定。

如果一个约束在表定义的最后才指定,这样的约束定义方法称为表级约束
如果一个约束涉及多个列的组合,那么就不能在每个列之后指定约束,而只能定义为表级约束。
定义表级约束的CREATE语句格式为:

CREATE TABLE 表名(
列 1 数据类型,
列 2 数据类型,
··
CONSTRAINT 约束名l 约束类型(列名),
CONSTRAINT 约束名2约束类型(列名),
. . . );

在五种约束中, NOT NULL约束只能以列级约束的形式定义,其余四种既可以以列级约束的形式定义,也可以以表级约束的形式定义因为表级约束是在所有列之后定义的,而不是在某个具体的列之后定义,所以在表级约束中要指定相关的列名。

外键约束的定义形式比较复杂,因为外键要与另一个表的主键进行关联,所以不仅要指定约束的类型和有关的列,还要指定与哪个表的哪个列进行关联。
如果在列级定义外键约束,定义的格式为:

CONSTRAINT 约束名 REFERENCES 表名(列名);

其中约束名是为这个外键约束起的名字。

FOREIGN KEY 为约束类型,即外键约束。

REFERENCES关键字指定与哪个表的哪个列进行关联。

如果要在表级定义外键约束,那么外键的定义代码放置在所有列的定义之后,它的格式为:
CONSTRAINT 约束名 FOREIGN KEY(外键列) REFERENCES 表名(列名);

约束作为一种附加在表上的数据库对象,它的信息也被记录在数据字典中。

与约束有关的数据字典有两个,一个是user_constraints,另一个是user_cons_columns
其中在数据字典user_constraints 中记录当前用户所拥有的约束的信息,如约束名、约束类型、约束所在的表、约束的状态等。
如果是外键,还记录了与之关联的主键名称。

数据字典视图USER_CONSTRAINTS各列及其意义如下:

OWNER  (Owner of the table) 
CONSTRAINT_NAME  (Name associated(关联) with constraint definition)                                  
CONSTRAINT_TYPE  (Type of constraint definition)                                               
TABLE_NAME  (Name associated with table with constraint definition)                       
SEARCH_CONDITION  (Text of search condition for table check)                                    
R_OWNER  (Owner of table used in referential constraint)                               
R_CONSTRAINT_NAME  (Name of unique constraint definition for referenced table)                   
DELETE_RULE  (The delete rule for a referential constraint)                                
STATUS  (Enforcement status of constraint - ENABLED or DISABLED)                     
DEFERRABLE  (Is the constraint deferrable - DEFERRABLE or NOT DEFERRABLE)                 
DEFERRED  (Is the constraint deferred(延迟约束) by default - DEFERRED or IMMEDIATE)              
VALIDATED  (Was this constraint system validated(验证)? - VALIDATED or NOT VALIDATED)         
GENERATED  (Was the constraint name system generated(产生)? - GENERATED NAME or USER NAME)    
BAD  (Creating this constraint should give ORA-02436. Rewrite it before 2000 AD. )
RELY  (If set, this flag will be used in optimizer(查询优化器))                                 
LAST_CHANGE  (The date when this column was last enabled or disabled)                      
INDEX_OWNER  (The owner of the index used by the constraint)                               
INDEX_NAME  (The index used by the constraint)                                            
INVALID  (无效的)
VIEW_RELATED (有关)

如果要进一步查询约束施加在哪个列上,就需要查询另一个数据字典了,它就是USER_ CONS_ COLUMNS

数据字典视图USER_CONS_COLUMNS各列及其意义如下:

OWNER  (Owner of the constraint definition) 
CONSTRAINT_NAME  (Name associated with the constraint definition)                                                   
TABLE_NAME  (Name associated with table with constraint definition)                                            
COLUMN_NAME  (Name associated with column or attribute of object column specified in the constraint definition) 
POSITION  (Original position of column or attribute in definition)

如何在创建表之后指定约束

在表创建之后再添加约束可能会带来这样的问题,如果表中已经有数据而这样的数据不满足将要添加的约束,那么约束是无法添加的。
因此最好的做法是在创建表之前充分考虑需要什么样的约束,在创建表的同时定义约束。

添加约束实际上也是对表的修改,因此添加约束也是通过执行ALTER语句完成的。

添加约束的ALTER语句格式为:

ALTER TABLE 表名称 ADD (CONSTRAINT 约束名称 约束类型 (列名称), CONSTRAINT 约束类型 (列名称));

如果要添加多个约束,在ADD子句的括号中指定多个用逗号分割的约束就好了。

除了NOT NULL之外,其他四个约束都可以通过ADD子句添加。

NOT NULL约束比较特殊,只能通过ALTER命令的MODIFY子句来添加。

添加NOT NULL子句约束的语法格式为:

ALTER TABLE 表名称 MODIFY 列名称 CONSTAINT 约束名称 NOT NULL;

约束的维护

如果希望去掉表上的某个约束,可以将其删除,也可以使其无效。

约束是不能被修改的,如果在表上已经建立了一个约束,现在希望把它改为另一种类型的约束,或者希望把它施加到另一个列上,只能先将这个约束删除,然后重新创建。

删除约束是通过执行ALTER命令的DROP子句来实现的。

删除约束的ALTER语句的语法格式为:

ALTER TABLE 表名称 DROP CONSTRAINT 约束名称;

如果要删除一个主键约束,首先要考虑这个主键列是否已经被另一个表的外键所关联,如果没有关联,可以直接删除,如果有关联,则不能直接删除。

要删除主键约束,必须使用CASCADE关键字,连同与之关联的外键约束一起删除。

删除主键约束的ALTER语句的语法格式为:

ALTER TABLE 表名称 DROP CONSTRAINT 主键约束名称 CASCADE;

在表中建立主键约束或UNIQUE约束时,在相关的列上将自动添加唯一性索引。

当从表中删除主键约束或UNIQUE约束时,与它们相关的索引也被删除。

如果希望一个约束暂时不起作用,可以使其无效。

使约束无效的操作是通过ALTER命令的DISABLE子句实现的。

 使约束无效的ALTER命令格式为:

ALTER TABLE 表名称 DISABLE CONSTRAINT 约束名称;

如果希望一个约束重新有效,可以执行带ENABLE的ALTER语句。

这时ALTER命令的格式为:

ALTER TABLE 表名称 ENABLE CONSTRAINT 约束名称;