1.4 Access数据库设计基础
设计一个满足用户需求、性能良好的数据库是数据库应用系统开发的核心问题之一。对于Access数据库的设计,主要任务就是设计出合理的、符合一定规范化要求的表(二维表格)及表之间的联系。
1.4.1 Access数据库设计步骤
Access数据库设计的一般步骤如下。
1.需求分析
数据库开发人员要与数据库的最终用户进行交流,详细了解最终用户的需求并认真进行分析,确定本数据库应用系统的目标、功能以及所涉及的数据。
2.确定数据库需要建立的表和各表包含的字段及主键
首先,根据数据库概念设计的思想,遵循概念单一化的原则,对需求分析的结果进行抽象处理,以确定数据库中的基本实体并绘制E-R图。
其次,将 E-R 图转换为关系模式,从而确定数据库中有哪些表(二维表格),每张表所包含的字段及其主键。主键字段中不允许有重复值或空值。
3.确定表之间的联系
确定表之间的联系也就是确定实体之间的联系,即确定表之间是一对一联系(1︰1)、一对多联系(1︰n),还是多对多联系(m︰n)。
4.优化设计
应用数据库规范化理论对每张表进行检查,以消除不必要的重复字段,降低数据冗余度。
1.4.2 数据库规范化
数据库规范化通常以关系数据库范式理论为指导,其目的是尽可能地消除数据冗余,保证数据的准确性和可靠性,以提高数据库的查询效率。关系数据库范式理论是在数据库设计过程中需要遵守的准则,这些准则称为规范化形式,即范式。
在实际的数据库设计中,通常会用到3种范式,即第一范式、第二范式和第三范式。下面分别对它们进行介绍。
1.第一范式(1NF)
1NF是关系数据库最基本的规范形式,不符合1NF的数据库就不是关系数据库。它要求表中的每一个字段值都必须是不可再分割的数据项,即一个字段中不能有多列值。例如,表1-2是不符合1NF的表,表1-3是符合1NF的表。
2.第二范式(2NF)
2NF是在1NF的基础上建立起来的,即要想符合2NF,必先符合1NF。2NF要求表中的每条记录必须是唯一的,而且记录的每个属性必须完全依赖于主键。所谓完全依赖于主键是指不能仅依赖主键中的一部分属性。如果存在不完全依赖于主键的属性,应该分离出来形成一个新表,新表与原表之间是一对多联系(1︰n)。
例如,表1-21是不符合2NF的学生选课信息表。该表以“学号+课程名称”为主键,每条记录对应一个学生某门课程的成绩。我们从表1-21中可以发现,“成绩”完全依赖主键,而“姓名”和“班级”仅依赖于学号,“学分”仅依赖于“课程名称”。
表1-21 不符合2NF的学生选课信息表
该学生选课信息表存在以下问题。
(1)数据冗余。同一个学生选修了 m 门课程,姓名和班级都会重复 m-1次。同一门课程有n个学生选修,学分就重复n-1次。
(2)更新异常。若调整了某门课程的学分,则该学生选课信息表中与该门课程相关的所有记录的学分值都必须更新,否则会出现同一门课程学分不同的情况。
(3)插入异常。假设要开设一门新课,暂时还没人选修。由于主键“学号”没有值,所以课程名称和学分都无法加入该学生选课信息表中。
(4)删除异常。假设有一批学生毕业了,他们的选课记录应该从该学生选课信息表中删除,这样有可能把某些课程的课程名称和学分也同时删除了,从而导致删除异常。
这里将表1-21拆分为3张表,如表1-22~表1-24所示,这样就符合2NF,解决了以上问题。
表1-22 学生表
表1-23 课程表
表1-24 选课成绩表
3.第三范式(3NF)
3NF是在2NF的基础上建立起来的,即要想符合3NF,必先符合2NF。3NF要求表中不存在非主属性对任意主属性的传递函数依赖。主属性是指能够唯一标识一条记录的所有属性。所谓传递函数依赖,是指如果存在主属性A决定非主属性B,而非主属性B决定非主属性C,则称非主属性C传递函数依赖于主属性A。
例如,表1-25是符合2NF但不符合3NF的教师表。该表的主键是“教师编号”,每条记录对应1个教师,所有属性都完全依赖于主键。表中的“教师编号”是主属性,“教师编号”决定了非主属性“院系名称”,而“院系名称”又可以决定非主属性“院长”,存在传递函数依赖。所以也会存在数据冗余、更新异常、插入异常和删除异常问题。
(1)数据冗余。一个院系有n个教师,院系名称和院长就重复n-1次。
(2)更新异常。若调整了某个院系的院长,则该教师表中与该院系相关的所有记录的院长值都必须更新,否则会出现同一院系院长不同的情况。
(3)插入异常。插入新教师的院系名称如果不存在,无法确定院长。
(4)删除异常。如果删除某个院系的所有教师,有可能把该院系名称和院长也同时删除。
表1-25 不符合3NF的教师表
这里将表1-25拆分为两张表,如表1-26和表1-27所示,这样就符合3NF。
表1-26 符合3NF的教师表
表1-27 院系代码表
另外,3NF还要求不要在数据库中存储可以通过简单计算得出的数据。这样不但可以节省存储空间,而且在拥有函数依赖的一方发生变化时,避免成倍修改数据的麻烦,同时也避免了修改过程中可能造成的人为错误。例如,表1-28是符合2NF但不符合3NF的课程表,该表的主键为“课程编号”。其中“课程编号”决定了“学时”,而“学分”可以根据学时计算得到(例如,1学分对应16学时)。或者也可以理解为“课程编号”决定了“学分”,而“学时”可以根据学分计算得到。所以“学时”和“学分”只能保留其中的1个。
表1-28 不符合3NF的课程表