Oracle数据库完整性约束概述

Oracle数据库完整性约束概述

概述

完整性约束是一种命名规则,用于限制一个或多个表中的列值。

这些规则可以防止向表中输入无效数据。此外,约束也可以防止当存在某些依赖项时删除表中的数据。

如果启用了约束,则输入或更新数据时,数据库会检查数据。不符合该约束的数据会被阻止输入。

如果禁用了约束,则不符合该约束的数据可以被允许输入数据库。

数据库在DML语句执行完成后才检查约束(默认情况)。

数据完整性简介

业务规则会指定一些条件和关系,它们要么必须始终为真,要么必须始终为假。例如,每个公司会定义其有关工资、 雇员人数、 库存跟踪,等方面的政策。保持数据的数据完整性很重要,它由数据库管理员或应用程序开发人员来确定,以遵从业务规则。

在设计数据库应用程序时,有多种选项用于保证存储在数据库中的数据的完整性。这些选项包括:

通过数据库触发器存储过程,强制实施业务

在数据库应用程序的代码中执行业务规则

在数据库中,表中的列级别定义完整性约束,用来限制数据库中的值的规则

完整性约束的优势

完整性约束是一个模式对象,它使用SQL来创建和删除。

若要强制实施数据完整性,请尽可能使用完整性约束,完整性约束包括如下优点:

**容易声明:**在定义或更改表时,使用 SQL 语句定义完整性约束,而无需任何额外的编程。SQL 语句易于编写,也易于排除编程错误。

**集中化的规则:**完整性约束定义在表上,并存储在数据字典中 。因此,由所有应用程序输入的数据都必须遵守相同的完整性约束。如果约束规则在表级发生了更改,应用程序不需要变更。

**加载数据时的灵活性:**当加载大量数据时,您可以暂时禁用完整性约束,以避免性能开销。当数据加载完成后,您可以重新启用完整性约束

完整性约束的类型

**非空约束 :**允许或不允许在指定的列插入或更新包含空值的行。

**唯一键约束 :**在相同的列、或多个列的组合中,不允许多个行具有相同的值,但允许一些值为空。

**主键约束 :**合并 NOT NULL 约束和唯一性约束。在相同的列、或多个列的组合中,不允许多个行具有相同的值,也不允许为空。

**外键约束 :**指定一个列作为外键,在外键和主键或唯一键之间建立关系,也称为引用键。

**检查性约束 :**要求某个数据库值服从指定的条件。

非空完整性约束

NOT NULL 约束要求表中的列不包含空值(空值即值的缺失)。

默认情况下,一个表中的所有列都允许空值。

NOT NULL 约束主要用于不能缺少值的列。

如果表已包含有行,不能直接添加一个具有 NOT NULL 约束的列,除非还为这个列指定了 DEFAULT 默认值的子句。

唯一性约束

唯一键约束要求在一个列或列集中的每个值是唯一的。

在一个表中,不允许多个行在有唯一键约束的列(唯一键)或列集(复合唯一键)上具有重复值。

数据库通过在键列上隐含创建或重用索引来强制执行唯一性约束。

对含有部分空值的复合唯一键约束中,在非空列中不能有相同的值(鉴于在多个列上的唯一键约束的搜索机制决定)。

主键约束

在一个主键约束中的列或列集,其值能唯一地标识行。

每个表只能有一个主键,起到确定行的作用,并确保不存在任何重复的行。

主键可以是自然键或代理键。自然键是由表中的现有属性组成的一个有意义的标识符。例如,一个自然键可能是查找表中的邮政编码。相比之下,代理键是一个系统生成的递增标识符,以确保在一个表中的唯一性。通常,由一个序列生成代理键。

数据库实现的主键约束可以保证如下行为:

1)任何两行在指定的列或列集上都不具有重复值。

2)主键列不允许空值。

数据库使用索引来强制主键约束。通常,在某列上创建的主键约束会隐含创建一个唯一索引和一个非空约束。

注意:

可以使用 CREATE UNIQUE INDEX 语句,显式创建一个唯一索引。

当你创建主键约束时,如果有一个现成的索引可用,则该主键约束会重用此索引,而不会隐式创建一个额外的新索引。

默认情况下,隐式创建的索引名称即是主键约束的名称,也可以为索引指定一个用户定义的名称。

可以通过在用来创建该约束的 CREATE TABLE或 ALTER TABLE 语句中包括 ENABLE 子句,来为索引指定存储选项。

外键约束

也称为参照完整性约束,只要两个表包含一个或多个公共列,则数据库可以通过一个外键约束来强制建立两个表之间的关系。

该约束要求定义约束的列中的每个值,必须与另一个指定表中的指定列中的值相匹配。

**外键:**约束定义中包含的列或列集,它引用了参考键。

外键可以定义在多个列上。但是,复合外键必须引用具有相同数量和相同数据类型列的复合主键或复合唯一键。

外键的值,可以要么匹配被引用主键或唯一键的值,要么为空。

如果一个复合外键的任何列为空,则该键的非空部分不一定要匹配父项中的任何相应部分。

**被引用键:**被外键所引用的表中的唯一键或主键。

**依赖表或子表:**包含外键的表。此表依赖于父表中被引用的唯一键或主键的值。

**被引用表或父表:**由子表的外键引用的表。正是该表中的被引用值决定了在子表中特定的插入或更新是否可被允许。

自引用完整性约束

外键引用同一个表中的父键。

空值和外键

关系模型允许外键的值可以匹配被引用主键或唯一键值,或者为空。例如,用户可以往 hr.employees 表插入行 ,而无需指定一个部门 id。

如果一个复合外键的任何列为空,则该键的非空部分不一定要匹配父项中的任何相应部分。

父键修改和外键

在父键被修改时,参照完整性约束可以指定在子表中的相关行上,执行以下某种操作之一:

对删除或更新操作,不采取任何动作

如果修改的结果会违反参照完整性,则直接报错,禁止修改。

级联删除

级联删除(DELETE CASCADE)即是当包含被引用键值的行被删除时,导致子表中的所有的外键依赖值所在行也会被删除。

对删除置空

删除置空(DELETE SET NULL)即是当包含被引用键值的行被删除时,导致子表中的所有的外键依赖值被全部置空。

索引和外键

总是应该为外键创建索引(除非引用的唯一键或主键永远不会被更新或删除),作为一个表设计原则。

在子表中的外键上建立索引提供了下列好处:

**可防止在子表上的全表锁定。**相反,数据库只需要在索引上获取一个行锁。

**消除在子表上进行全表扫描的需要。**作为一个说明,假定用户从部门表中删除部门 10 的记录。如果没有为 employees.department_id 建立索引,则数据库必须扫描 employees 表,以查看是否存在属于部门 10 的雇员。

检查性约束

在一个列或列集上的检查约束,要求所指定的条件为真,或对每一行来说是未知的。

如果 DML 语句导致约束条件的计算结果为假,则 SQL 语句将被回滚。

检查约束的主要好处是,具备强制执行非常具体的完整性规则的能力。

例如可以使用检查性约束在 hr.employees 表中强制执行下列规则:

在 salary 列中不能有大于 10000 的值。

commission 列必须有一个值,但不能大于 salary。

完整性约束的状态

指定数据库应如何及何时强制执行该约束条件,从而确定约束状态。

对现有数据和新数据的检查――针对数据

数据库使您可以指定将某个约束应用于现有数据还是应用于新数据。如果约束是启用的,则当输入或更新数据时,数据库会检查新的数据。不符合该约束的数据不能输入到数据库。

可以设置约束来验证 (VALIDATE) 或不验证 (NOVALIDATE) 现有数据。

如果指定了 VALIDATE ,则现有数据必须符合该约束。例如,对employees.department_id 启用 NOT NULL 约束并将其设置为VALIDATE, 则会检查每个现有行都有一个部门 id。

如果指定了 NOVALIDATE,则现有数据不需要符合该约束。

VALIDATE 和 NOVALIDATE 的行为都取决于约束是启用的还是禁用的。
ENABLE+VALIDATE(默认值) :现有的和将来的数据都必须遵守约束。如果试图在一个已填充的表上应用一个新的约束,而现有的行违反该约束,则会导致一个错误。

ENABLE+NOVALIDATE:数据库会检查该约束,但不需要对所有行为真。因此,现有的行可以违反该约束,但新的或修改后的行必须遵守该约束。

DISABLE+VALIDATE:数据库禁用该约束、删除其上的索引,并防止修改受约束的列。

DISABLE+NOVALIDATE:不检查约束,也不需要为真。

可延迟约束――针对约束

约束检查时间点:单个SQL语句结束检查或者整个事务结束时检查

约束可能处于不可延迟(默认值) 或可延迟两种状态之一。

该状态确定数据库何时检查约束的有效性。

不可延迟约束

数据库在每个语句的结尾检查约束。如果违反了约束,则该语句被回滚。

可延迟约束

可延迟约束允许事务使用 SET CONSTRAINT 子句将约束检查推迟到发出COMMIT 语句时。

如果你对数据库中做了可能违反约束的更改,则此设置让您有效地禁用该约束,直到完成所有更改。

可以设置数据库检查可延迟约束时的默认行为:

INITIALLY IMMEDIATE

数据库在每个语句执行后,立即检查约束。如果违反了约束,则数据库回滚该语句。基本和不延迟约束一样。

INITIALLY DEFERRED(默认值)

发出 COMMIT 时,数据库检查约束。如果违反了约束,则数据库回滚该事务。

INITIALLY IMMEDIATE和INITIALLY DEFERRED的区别:假定一个在 employees.last_name 列上的可延迟的 NOT NULL 约束被设置为 INITIALLY DEFERRED。用户创建了一个包含 100 个 INSERT 语句的事务,其中一些在 last_name 列上具有空值。当用户尝试提交时,数据库将回滚所有 100 个语句。但是,如果这种限制被设置为 INITIALLY IMMEDIATE,则数据库将不会回滚整个事务。(只会回滚那些含有 NULL值的行)

约束级联操作

如果一个约束导致一个动作(例如级联删除或者置空),则数据库认为此动作是引发它的语句的一部分,而无论该约束是可延迟的或立即的。

例如,从 departments 表中删除一行,会导致删除 employees 表中引用了相应的被删部门的雇员。在这种情况下,从 employees 表中删除雇员被认为是对 departments 表执行的 DELETE 语句的一部分。

约束示例

复制代码
CREATE TABLE employees
 ( employee_id NUMBER(6) primary key
 , first_name VARCHAR2(20) not null
 , last_name VARCHAR2(25) CONSTRAINT emp_last_name_nn NOT NULL
 , email VARCHAR2(25)  CONSTRAINT emp_email_nn NOT NULL
 , phone_number VARCHAR2(20)
 , hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL
 , job_id VARCHAR2(10  CONSTRAINT emp_job_nn NOT NULL
 , salary NUMBER(8,2)
 , commission_pct NUMBER(2,2)
 , manager_id NUMBER(6)
 , department_id NUMBER(4)
 , CONSTRAINT emp_salary_min CHECK (salary > 0)
 , CONSTRAINT emp_email_uk UNIQUE (email)
 , CONSTRAINT fk_dept_id FOREIGN KEY(department_id)  REFERENCES department(department_id) ON DELETE CASCADE
 ) ;
 
 create table  department (department_id  number  primary key,department_name varchar2(30));
 
 //下面都是建表时,明确的约束,类似如下:
 employee_id NUMBER(6) primary key
 first_name VARCHAR2(20) not null
 last_name VARCHAR2(25) CONSTRAINT emp_last_name_nn NOT NULL
 email VARCHAR2(25)  CONSTRAINT emp_email_nn NOT NULL
 CONSTRAINT emp_salary_min CHECK (salary > 0)
 CONSTRAINT emp_email_uk UNIQUE (email)
 CONSTRAINT fk_dept_id FOREIGN KEY(department_id)  REFERENCES department(department_id) ON DELETE CASCADE
相关推荐
AKA__Zas2 小时前
视图与索引
数据库·学习方法
毅炼2 小时前
MySQL 常见问题总结(1)
java·大数据·数据库
路由侠内网穿透2 小时前
本地部署开源发票管理系统 Invoice Ninja 并实现外部访问
运维·服务器·数据库·物联网·开源
m0_640309302 小时前
c++如何判断两个文件路径是否物理指向同一个磁盘文件_equivalent【详解】
jvm·数据库·python
AI周红伟2 小时前
《智能体应用交付实操:OpenClaw+Skills+RAG+Agent智能体应用案例实操和智能体交付的方案设计》
大数据·数据库·人工智能·科技·gpt·深度学习·openclaw
一 乐2 小时前
饮食营养信息|基于springboot + vue饮食营养管理信息平台系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·饮食营养管理信息系统
Shorasul2 小时前
Django 信号中为 ImageField 指定自定义保存路径的正确实践
jvm·数据库·python
RInk7oBjo2 小时前
大模型应用:批量文档摘要与分类实践:本地合同、报告数据处理与导出
大数据·数据库·人工智能
Wyz201210242 小时前
CSS如何实现移动端点击高亮去除_设置tap-highlight-color
jvm·数据库·python