内容主要来源于Oracle官方文档(官网英文版和网络中文版)
Oracle Database Concepts
1.数据完整性简介
业务规则要求数据符合一定的条件和关系,比如非空、默认值等等。
1.1 保证数据完整性的技术
保证存储在数据库中数据的完整性有以下几种方法:
1.通过存储在数据库中的触发器,强制实施业务规则;
2.使用存储过程完全控制数据的访问;
3.在数据库应用中强制执行业务规则;
4.使用数据库完整性约束。
1.2 完整性约束的优点
完整性约束是一个能够通过SQL被创建和删除的模式对象。为了实现数据完整性,应尽量使用完整性约束。
完整性约束比比其他替代的数据完整性方案有以下优点:
1.易声明:当定义和修改表时,可以使用SQL语句定义完整性约束。
2.规则集中:完整性约束被定义在表上并存储在数据字典中。应用程序键入的数据必须符合相同分的规则。当约束在表级变更时,无需修改应用程序;
3.加载数据时灵活:
2.完整性约束类型
行内规范约束:作为列或者属性的一部分定义的约束
行外规范约束:作为表的定义的一部分的约束
约束类型 | 描述 |
---|---|
NOT NULL | 不允许插入或更新包含指定列空值的行 |
唯一键 | 在相同的列或者列组合中,禁止多行有相同的值但允许为空 |
主键 | NOT NULL约束和唯一约束的组合 |
外键 | 指明一列作为外键,用来在外键与主键或唯一键之间建立联系,也叫引用键 |
检查性约束 | 需要数据库中的值服从指定的条件 |
2.1 非空完整性约束
非空约束要求表中的列不包含控制。空值就是没有值。默认所有的行可为空。
只有在为列指定默认值之后或者表中没有任何行时,才能为列添加非空约束。
2.2 唯一约束
唯一约束要求列或者列集中的值唯一。表中具有唯一键约束的列或者列集在表中没有重复的行。
除非列上同时被定义了非空约束,否则null值也满足唯一键约束。因此,列上通常同时存在唯一键约束和非空约束。该组合强制用户输入唯一值,并且消除了新值和旧值冲突的可能。
注意:含有空值的复合唯一约束,非空列中不能有重复值。
2.3 主键约束
在主键约束中,一列或多列值能唯一标识一行。每个表只能有一个主键来确定不包含重复行。
主键可以是自然键和代理键。自然键是一个有表中现存属性组成的有意义的标识符。代理键是一个系统生成的自增长的标识符,以确保在表中的唯一性,通常由序列来生成。
主键可以确保两件事:
1.任意两行在指定的列或列集上都没有重复值;
2.主键列不允许为空;
数据库使用索引来实现主键约束。在创建主键约束时,通常会隐式创建一个唯一索引和非空约束,有两个例外情况:1.使用可延迟的约束选项来创建主键时,生成的索引不是唯一的;2.创建主键约束时,如果有一个现成的索引可用,则主键约束会重用此索引,而不会隐式创建额外的新索引。
默认情况下,隐式创建的索引名就是主键约束的名称。
2.4外键约束
外键约束要求定义约束列中的每个值必须与另一个指定表中的指定列中的值相匹配。外键约束可以定义在多个列上。但是,复合外键必须引用具有相同数量和相同数据类型列的复合主键或复合唯一键。外键的值,要么匹配被引用主键或唯一键的值,要么为空。如果复合外键的任何列为空,则该键的非空部分不一定要匹配父相中的任何相应部分。
关系模型允许外键的值可以匹配被引用主键或唯一键值,或者为空。复合外键的一列为空,则其他非空列不一定匹配父表相应部分。
父键的修改和外键: 1、正常情况下,删除和更新不会发生行为(存在引用的数据);2、级联删除:子表中引用父表键值的行随着父表的键值删除被删除;3、对删除置空:被引用键值的行被删除是,子表中的依赖值被置空。
索引和外键: 总是要为外键建立索引。例外是父表中的被引用键永远不会被更新或这删除。在子表的外键中建立索引的好处:1.防止子表上的全表锁定;2.消除子表上进行全表扫描的需要。
2.5 检查约束
检查约束要求列或者列集对于指定的条件为真或者未知。
例如:
SQL> ALTER TABLE employees ADD CONSTRAINT max_emp_sal CHECK (salary < 10001);
SQL> INSERT INTO employees (employee_id,last_name,email,hire_date,job_id,salary)
1 VALUES (999,'Green','BGREEN',SYSDATE,'ST_CLERK',20000);
.
.
.
ERROR at line 1:
ORA-02290: check constraint (HR.MAX_EMP_SAL) violated
3.完整性约束状态
3.1 对修改的或已存在的数据的检查
修改的新数据 | 已存在的数据 | 总结 |
---|---|---|
enable | validate | 新数据和现有数据都必须遵守约束。如果已有数据违反约束,会报错 |
enable | novalidate | 检查约束,不验证约束,就是说现有的行可以违反约束,新的行必须遵守约束 |
disable | validate | 禁用约束并删除上面的索引,并防止修改约束列 |
disable | novalidate | 不检查约束,不确保为真 |
3.2 可延迟约束
约束可能处于可延迟和不可延迟(默认)两种状态。该状态确定数据库核实检查约束的有效性。
不可延迟约束:如果约束为不可延迟约束,数据库不会将检查约束的工作延迟到事务结束,而是在语句的结尾检查约束,如果违反了约束,语句则回滚。
可延迟约束:通过使用SET CONSTRAINT语句,推迟检查约束,直到发出COMMIT语句。
可延迟约束可以指定以下属性:
DEFERRABLE INITIALLY IMMEDIATE:数据库在执行语句后立即检查约束,违反约束会回滚语句,不会回滚事务;
DEFERRABLE INITIALLY DEFERRED:数据库在COMMT时检查约束,违反了就回滚事务;