1.4 完整性及范式理论
数据库中的数据是从外界输入的,而在输入数据时会发生种种原因,如输入无效或错误信息等。保证输入的数据符合规定,是多用户的关系数据库系统首要关注的问题,也是数据完整性的重要特性。
因此,在设计数据库时,最重要的是确保数据正确存储到数据库的表中。当然使用正确的数据结构,可以极大地简化数据库管理系统(如查询、窗体、报表、代码等)。这就是表设计的一种规范,也称为“数据库规范化”。
1.4.1 数据库完整性
数据库完整性(Database Integrity)是指数据库中数据的正确性和相容性。数据库完整性由各种各样的完整性约束来保证,所以数据库完整性设计就是数据库完整性约束的设计。
数据库完整性约束可以通过DBMS或应用程序来实现,基于DBMS的完整性约束作为模式的一部分存入数据库中。在关系数据模型中一般将数据完整性分为三类。
1.实体完整性
实体完整性规定表的每一行在表中是唯一的实体。实体完整性和参照完整性是关系模型必须满足的完整性约束条件,被称作是关系的两个不变性。而实体完整性规则如下。
❏实体完整性是要保证关系中的每个元组都是可识别和唯一的。
❏实体完整性规则的具体内容是:若属性A是关系R的主属性,则属性A不可以为空值。
❏实体完整性是关系模型必须满足的完整性约束条件。
❏关系数据库管理系统可以用主关键字实现实体完整性,这是由关系数据库默认支持的。
实体完整性规则是针对关系而言的,而关系则对应一个现实世界中的实体集。现实世界中的实体是可区分的,它们具有某种标识特征;相应地,关系中的元组也是可区分的,在关系中用主关键字做唯一性标识。例如,“图书情况”表则对应现实世界中图书信息的实体集。而【图书编号】字段中每个产品都能表示实体的唯一性。
其中主关键字中的属性(即主属性)不能取空值。如果主属性取空值,则意味着关系中的某个元组是不可标识的,即存在不可区分的实体,这与实体的定义也是矛盾的。
2.参照完整性
在关系模型中,实体与实体之间的关联同样采用关系模式来描述。通过引用对应实体的关系模式的主关键字来表示对应实体之间的关联。
设F是基本关系R的一个或一组属性,但不是R的主关键字,若F与基本关系S的主关键字K相对应,则称F是基本关系R的外键。
其中R为参照关系,S为被参照关系(也称目标关系),而且F和K必须定义在同一个域上。
如上所述,【职工编号】字段是【出货单】表中的属性(字段),并且不是主关键字,而【职工编号】字段与【职工信息】表中的【员工编号】字段相对应。因此,【职工编号】是【出货单】表的外键,【出货单】表为参照关系,【职工信息】表为被参照关系。
3.用户定义的完整性
最常见的是限定属性的取值范围,即对值域的约束。如某个属性的值必须唯一,某个属性的取值必须在某个范围等。
例如,在【常规】选项卡中,将【格式】设置为“长日期”,将【输入掩码】设置为“9999\年99\月99\日;0;”,将【默认值】设置为“=Date()”表达式。
1.4.2 数据库范式理论
数据库的设计范式是符合某一种级别的关系模式的集合,构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式。关系数据库中的关系必须满足一定的要求,即满足不同的范式。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范式(5NF)和第六范式(6NF)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多要求的范式称为第二范式(2NF),其余范式依次类推。一般说来,数据库只需满足第三范式(3NF)就行了。
1.第一范式(1NF)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的值。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。
在第一范式(1NF)中,表的每一列只包含一个实体的信息。
对于上图中的“客户信息”表,不能将每一位客户的信息都放在一列中显示,也不能将其中的两列或多列在一列中显示;每一行只表示一位客户的信息,一个客户的信息在表中只出现一次。简而言之,第一范式就是无重复的列。
2.第二范式(2NF)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
第二范式(2NF)要求数据库表中的每个行(实例)必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。
在上述表中,可以通过【出货ID】字段,来标识出货的唯一性。因此每份出货单可以被唯一地区分,这个唯一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。
3.第三范式(3NF)
满足第三范式(3NF)必须先满足第二范式(2NF)。并且数据表中的任何两个非主键字段的数据值之间不存在函数信赖关系,那么该数据表满足第三范式(3NF)。
在上述【出货单明细】表中,列出了【产品编号】字段,就不能再将【产品名称】、【单价】、【系列ID】等与产品有关的信息列入到【出货单明细】表中。用户应该根据第三范式来构建该表,否则将会产生大量的数据冗余。
4.BC范式(BCNF)
如果关系模式R∈1NF,对任何非平凡的函数依赖X→Y(YX),X均包含码,即每个非主属性既不部分依赖于码,也不传递依赖于码,且在该关系中,所有的决定因素都包含码,即R∈BCNF。BCNF又称扩充的第三范式或修正的第三范式。
由BCNF的定义可知,一个满足BCNF的关系应该具有以下性质。
❏所有的非主属性对每一个码都是完全函数依赖。
❏所有的主属性对每一个不包含它的码,也是完全函数依赖。
❏没有任何属性完全函数依赖于非码的任何一组属性。
显然一个关系如果属于第三范式,它未必属于BCNF,但如果它属于BCNF,则一定属于第三范式。如果一个关系数据库中的所有关系模式都属于BCNF,那么在函数依赖范畴内,已实现了模式的彻底分解,达到了最高的规范化程度,消除了插入异常和删除异常。下表为一个满足BC范式的关系。
例如,在【工作人员】表中ID为主键,其决定【姓名】属性。该表中任何一对决定关系中,既不存在部分函数依赖,也没有传递函数依赖,在函数依赖范畴实现了完全分解,彻底消除了插入异常和删除异常。
5.第四范式和第五范式
如果关系中的数据仅仅涉及函数依赖,它满足BCNF范式已经实现了完全分解,不存在任何数据冗余和操作异常等问题。但是如果该关系涉及多值依赖,BCNF范式就不能保证它不存在任何数据冗余和操作异常。如果要想在存在多值依赖的情况下进一步处理数据关于多值依赖,需要讨论是否满足第四范式和第五范式。
事实上,函数依赖只是多值依赖的一种特殊情况,而多值依赖又是另外一种更高依赖——连接依赖的特殊情况。关于函数依赖以上的其他依赖情况在本书中就不进行详细论述。
从上面的叙述中可以看出,数据表规范化的程度趆高,数据冗余就越少,同时造成人为错误的可能性也越小,在查询检索时需要做的关联等工作就越多,数据库在操作过程上需要访问的数据表以及之间的关联也就越多。
因此,在数据库设计的规范化过程中,需要根据数据库需求的实际情况,选择一个折中的规范化程序。
6.关系模式规范化步骤
规范化的基本思想是逐步消除数据依赖中不合适的部分,使模式中的各关系模式达到某种程度的“独立”。因此,设计原则步骤,应该让一个关系描述一个概念、一个实体或实体间的一种联系。若多于一个概念就把它“分离”出去。
在上述图中,对1NF关系进行投影,消除原关系中非主属性对主键的函数依赖,将1NF关系转换成为若干个2NF关系。
对2NF关系进行投影,消除原关系中非主属性对主键的传递函数依赖,从而产生一组3NF。
对3NF关系进行投影,消除原关系中主属性对主键的部分函数依赖和传递函数依赖(也就是说,使决定属性都成为投影的候选键),得到一组BCNF关系。
对BCNF关系进行投影,消除原关系中非平凡且非函数依赖的多值依赖,从而产生一组4NF关系。
总之,在设计数据库模式结构时,必须以现实世界的实际情况和用户应用需求作进一步分析,确定一个合适的、能够反映现实世界的模式。即上面的规范化步骤可以在其中任何一步终止。