



数据库完整性是指数据库中数据的正确性、有效性和相容性(一致性)。设计数据库的一个重要步骤就是保证数据的完整性。
数据库完整性由各种各样的完整性约束来保证,因此可以说数据库完整性设计就是数据库完整性约束的设计。数据库完整性约束可以通过DBMS或应用程序来实现,基于DBMS的完整性约束可作为模式的一部分被存入数据库中。
数据库完整性对于数据库应用系统非常关键,其作用主要体现在以下几个方面:
①数据库完整性约束能够防止合法用户使用数据库时向数据库中添加不合语义的数据。
②利用基于DBMS的完整性控制机制来实现业务规则,易于定义,容易理解,而且可以降低应用程序的复杂性,提高应用程序的运行效率。同时,由于DBMS的完整性控制机制是集中管理的,因此其比应用程序更容易实现数据库的完整性。
③合理的数据库完整性设计,能够同时兼顾数据库的完整性和系统的效能。比如装载大量数据时,只要在装载之前临时使基于DBMS的数据库完整性约束失效,此后再使其生效,就能保证既不影响数据装载的效率又能保证数据库的完整性。
④在应用软件的功能测试中,完善的数据库完整性有助于尽早发现应用软件的错误。
完整性约束主要有四种类型:实体完整性(Entity Integrity)、参照完整性(Referential Integrity)、域完整性(Domain Integrity)、用户定义完整性(User-defined Integrity)。
实施数据完整性有两种方式:声明数据完整性和过程数据完整性。声明数据完整性就是通过在对象定义中来实现。而过程完整性是通过在脚本语言中定义来实现的,当执行这些脚本时就可以强制完整性的实现。本节着重介绍声明数据完整性,具体的实施途径请参考表2-14。
表2-14 数据完整性的实施途径
本章第一节曾介绍过,实体完整性要求主键不能为空值,即单列主键不接受空值,复合主键的任何列也不接受空值,其目的就是保证数据库表中的每一个元组都是唯一的。实体完整性可以定义在表级,也可以定义在列级,但是当表的主键是复合主键时,实体完整性就必须定义在表级。
【例2-16】 创建一张用户表(User_List),主键是用户号(UserID)。
或者
【例2-17】 创建一张订单信息表(Order_ Information),主键为订单号(OrderID)和书籍编号(BookID)。
如果在创建表时未定义主键,可以用ALTER TABLE语句添加。
【例2-18】 给用户表(User_List)添加主键。
参照完整性定义的是表与表之间的联系,目的是确保关联的表之间的数据保持一致,即不允许在一个关系中引用在另一个关系中不存在的元组。参照完整性既可以定义在表级,也可以定义在列级。
【例2-19】 创建订单信息表(Order_ Information),主键为订单号(OrderID)和书籍编号(BookID),外键为订单号(OrderID)和书籍编号(BookID)。
或者
在定义参照完整性时要注意,必须先定义主表(被参照表),因为只有被参照表关系建立后,参照关系才能存在。
如果在创建表时未定义参照完整性,可以用ALTER TABLE语句添加参照完整性。
【例2-20】 添加订单信息表(Order_Information)的参照完整性约束。
域完整性是指数据表中列的数据有正确的数据类型、格式和有效的数据范围,用于保证给定字段中数据的有效性,即保证数据的取值在有效的范围内。例如:用户性别只能是男和女、年龄不能为负值、书籍价格要大于0等。
【例2-21】 若将订单信息表(Order_ Information)中的订单号设为char(8)类型,则表示订单号须由8位字符组成,少于或超过8 位、带有非有效字符均是无效订单,这是限制类型的方法。
不同的数据库系统根据应用环境的不同,需要对其数据实施一些特殊的约束条件,因此用户可以自行定义具体环境下的数据约束条件。
通常用户在建表时可以定义以下三种完整性约束或添加完整性约束:
(1)列值非空(NOT NULL)。
(2)列值唯一(UNIQUE)。
(3)列值是否满足一个布尔表达式(CHECK)。
例2-22定义了一个用户定义完整性,以保证折扣价必须小于等于原始价格。
【例2-22】 建立书籍信息表Book_ Information (BookID,ISBN,BookName,Author,PressID,PublishDate,Pages,Edition,CategoryID,TotalNum,Price,DiscountPrice)。
完整性约束条件作用的对象可以是列、元组、关系三种。其中列级约束主要是关于列的类型、取值范围、精度、排序等的约束条件;元组约束是关于元组中各个字段间的联系的约束;关系约束(表级约束)是关于若干元组间、关系集合上以及关系之间的联系的约束。
而完整性约束条件涉及的这三类对象,其状态可以是静态的,也可以是动态的。所谓静态约束是指数据库每一种确定状态时的数据对象所应满足的约束条件,它是反映数据库状态合理性的约束,这是最重要的一类完整性约束。动态约束则是指数据库从一种状态转变为另一种状态时新、旧值之间所应满足的约束条件,它是反映数据库状态变迁的约束。
完整性检查是围绕这些完整性约束条件进行的,综上所述,可以将完整性约束的表现形式分为六类,如表2-15所示。
表2-15 完整性约束的表现形式
(1)静态列级约束。它是对一个列的取值域的说明,是最常用也是最容易实现的一类完整性约束,它包括对数据类型的约束(数据的类型、长度、单位、精度等)、数据格式的约束、取值范围或取值集合的约束、空值的约束等。如例2-22 中对BookName的声明规定了书名不能超过20个字符,而对ISBN的声明则规定了该属性值不能为空。
(2)静态元组约束。一个元组是由若干个列值组成的,静态元组约束就是规定元组的各列之间的约束关系。如发货量不能超过订货量,发货时间不能早于下单时间,书籍折扣价不能高于原价等。
(3)静态关系约束。一个关系的各个元组之间或若干关系之间存在的各种联系或约束就是静态关系约束,它包括实体完整性约束、参照完整性约束(外键约束)、函数依赖约束、统计约束。如例2-22中把BookID声明为主键,把PressID和CategoryID声明为外键。
(1)动态列级约束。它包括两类,一是修改列定义时的约束,如当把允许空值的列改为不允许空值时,如果该列目前存在空值,则拒绝修改;二是修改列值时的约束(新旧值之间需要满足某种约束条件),如图书新价格调整不得低于原来价格。
(2)动态元组约束。它是指修改元组值时,元组中各个字段间需要满足某种约束条件,如图书价格调整时新价格不得低于原来折扣价的2倍。
(3)动态关系约束。它是指加在关系变化前后状态上的限制条件。