第7章 数据库
学习目标
- 解释数据库、数据库管理系统、数据库系统的含义。
- 说明关系模型的基本概念、三类完整性约束和用户定义的完整性。
- 运用函数依赖、第一范式、第二范式和第三范式分析简单关系模式,并完成规范化。
- 掌握实体-联系模型的基本表示方法,以及从概念模型向关系模式转换的规则。
引言
数据库技术是数据管理技术发展到一定阶段的产物,也是现代信息系统的重要支撑。数据管理先后经历了人工管理、文件系统和数据库系统三个阶段:早期数据依附于程序、处理结束即不保留;文件系统实现了数据的长期保存,但冗余高、共享有限、独立性差;数据库系统则由数据库管理系统统一管理数据,实现了数据共享、冗余可控和较高的数据独立性。人们使用数据库,不仅是为了长期保存数据,更是为了在统一规则下组织数据、控制数据质量、支持多用户共享,并从数据中持续获得有价值的信息。
本章从数据处理和数据管理的基本概念出发,首先介绍数据库系统的组成与主要目标、三级模式与二级映像,以及集中式与分布式部署结构;然后讨论数据库管理系统的数据定义、数据操纵、运行控制、数据维护与数据通信五大功能。接着阐述数据模型的含义与抽象层次,重点讲解关系模型的基本术语、候选键、主键与外键,并介绍层次模型、网状模型、面向对象及新型数据模型。在此基础上,系统介绍数据库设计的六个阶段——需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施与运行维护,说明E-R模型向关系模式的转换规则;再讨论实体完整性、参照完整性与用户定义的完整性;最后以函数依赖为理论基础,讲解第一范式、第二范式、第三范式及规范化分解方法,为后续学习数据仓库、数据挖掘奠定基础。
7.1 数据处理与数据库概述
7.1.1 数据、信息与数据处理
数据是客观事物属性的符号表示,可以是数字、文字、图像、声音或传感器采集结果。信息则是经过加工处理后、能够消除不确定性并支持决策的数据表达。数据处理是将原始数据转化为信息的过程,通常包括采集、编码、存储、分类、检索、统计、分析、传输和维护等环节。例如,在物流配送系统中,车辆位置、货物重量、装卸时间和客户签收记录本身都是数据;将这些数据汇总后形成的运输时效分析、库存周转率报表和异常预警,才真正构成决策所需的信息。
数据处理、数据管理与信息形成之间的关系可用图7-1表示。
图7-1 数据处理的基本过程
从能力分工看,人脑在识别、理解、推理和综合判断方面具有优势,而计算机在大规模存储、高速运算、重复处理和精确执行方面更具优势。数据库技术正是在计算机数据处理能力不断增强的背景下发展起来的,它使数据从分散的、静态的记录,演变为可共享、可控制、可维护、可持续利用的组织化资源。
7.1.2 数据管理技术的发展阶段
数据管理技术的发展经历了由低级到高级、由分散到统一、由紧耦合到高独立性的演变过程。总体来看,可以分为人工管理阶段、文件系统阶段和数据库系统阶段。
(1) 人工管理阶段
人工管理阶段大致在20世纪50年代中期以前。计算机主要用于科学计算,数据量小,外存以纸带、卡片、磁带为主,没有操作系统和专门的数据管理软件。数据由程序自行管理,随程序运行而存在,处理结束即不保留,数据依附于程序。
图7-2 人工管理阶段示意图
(2) 文件系统阶段
20世纪50年代后期到60年代中期,磁盘、磁鼓等直接存取设备出现,操作系统日益完善,数据可以文件形式长期保存在外存,由文件系统负责读写。但文件面向单一应用设计,同一数据在多个文件中重复存储,难以共享,文件格式变化时程序也需同步修改。例如,教务处、财务处和图书馆各自维护学生信息文件,学生转专业时若更新不同步,就会产生数据不一致。
图7-3 文件系统阶段示意图
(3) 数据库系统阶段
20世纪60年代后期起,数据量迅速增长,共享需求增强,数据库管理系统应运而生。1968年IBM推出商品化的信息管理系统IMS;1969年DBTG报告提出数据库技术的概念和方法;1970年起E. F. Codd发表关系模型论文,奠定了关系数据库的理论基础。数据不再从属于单个应用,而是由DBMS统一管理、供整个组织共享的重要资源。
图7-4 以数据库为中心的数据共享示意图
三个阶段的对比如下:
表7-1 人工管理、文件系统与数据库系统三阶段对比
| 对比项 | 人工管理阶段 | 文件系统阶段 | 数据库系统阶段 |
|---|---|---|---|
| 数据保存 | 不长期保存 | 长期保存在文件中 | 长期保存在数据库中 |
| 管理者 | 应用程序 | 文件系统 | 数据库管理系统 |
| 数据结构 | 无结构,由程序定义 | 文件内有结构,文件间无联系 | 整体结构化,表内表间有联系 |
| 共享性 | 无法共享 | 共享有限 | 共享性高 |
| 冗余度 | 高 | 较高 | 冗余可控 |
| 独立性 | 差 | 较差 | 较高 |
| 一致性与安全 | 无 | 缺乏统一约束 | 通过权限、约束、事务保障 |
| 并发与恢复 | 无 | 并发支持较弱 | 支持并发控制和故障恢复 |
数据库系统的核心优势并不只在于“能存更多数据”,而在于“能以统一、可靠、可扩展的方式组织和使用数据”。
7.2 数据库基本概念
7.2.1 数据库系统的组成
一个完整的数据库系统通常由以下几个部分组成:
数据库系统不是单纯的软件产品,而是技术、数据、人员和管理规则共同构成的运行体系。
从软件层次看,数据库系统通常以硬件和操作系统为基础,DBMS在操作系统支持下工作,应用程序则通过DBMS访问数据库。DBA既参与数据库设计,又负责存储结构、权限、完整性约束、备份恢复、性能监测和重构等工作;应用程序员开发面向最终用户的应用系统,最终用户则通过应用界面或查询工具使用数据库。对于小型系统,DBA职责可能由应用程序员或最终用户兼任;对于大型系统,DBA通常是一个专业团队。
7.2.2 数据库系统的主要目标
数据库系统建立的根本目标在于提高数据资源的组织效率和使用价值。
首先,数据库系统要实现数据共享,使不同部门和不同应用能够访问一致的数据来源,并通过统一建模降低数据冗余,减少重复存储和重复维护。在此基础上,系统还要提高数据独立性,使应用开发与底层存储细节尽可能解耦,从而降低数据结构变化对应用程序的影响。
其次,数据库系统要保证数据的一致性与完整性,确保数据符合业务规则和语义约束;同时支持多用户并发访问,在并发环境下保证结果正确、状态一致。
最后,数据库系统还应具备故障恢复能力,使系统在异常或断电后能够恢复到正确状态,并通过身份认证、授权和审计等手段增强安全性,防止非法访问与滥用。
7.3 数据库系统的模式结构
7.3.1 三级模式结构
为了提高数据独立性,数据库系统通常采用三级模式结构,即外模式、概念模式和内模式。
在讨论三级模式之前,需要区分“模式”与“实例”。模式是对数据库全体数据逻辑结构和特征的描述,只涉及数据的“型”,不涉及具体数据值;实例则是模式在某一时刻的具体值。例如,学生关系模式可以定义为(学号,姓名,性别,出生日期,专业号),而某一年级学生记录的具体集合则是该模式的一个实例。模式相对稳定,实例则随数据更新不断变化。
1. 外模式
外模式又称用户模式或子模式,是数据库用户看到和使用的数据逻辑结构。不同用户可能只关心数据库中的局部数据,因此一个数据库通常可以有多个外模式。例如,教务管理系统中的教师只能看到课程和成绩相关数据,财务人员则主要看到收费和结算相关数据。
2. 概念模式
概念模式又称逻辑模式,是数据库中全体数据的逻辑结构和特征描述,是所有用户共同的数据视图。它回答“数据库整体上存了哪些数据、这些数据之间有什么联系”这一问题。一个数据库通常只有一个概念模式。
3. 内模式
内模式又称存储模式,是数据在数据库内部的物理组织方式描述,包括存储记录格式、索引组织、压缩方式和访问路径等。内模式直接面向物理存储,是DBMS实现高效访问的重要基础。
7.3.2 二级映像与数据独立性
三级模式结构之所以有价值,在于模式之间存在映像关系,从而保证数据独立性。
- 外模式/概念模式映像:定义外部视图与全局逻辑结构之间的对应关系,用于保证逻辑独立性。
- 概念模式/内模式映像:定义逻辑结构与物理存储结构之间的对应关系,用于保证物理独立性。
如果数据库增加了某些存储优化措施,例如建立索引、改变文件组织方式,只要概念模式不变,应用程序通常无需修改,这就是物理独立性。若全局逻辑结构做了适度调整,只要外模式保持稳定,面向用户的程序也可以保持不变,这就是逻辑独立性。
三级模式与二级映像共同构成了数据库体系结构,其层次关系可用图表示。
图7-5 数据库系统的三级模式结构与二级映像
7.3.3 数据库系统的部署结构
从系统部署方式看,数据库系统可分为集中式和分布式两大类。
1. 集中式部署
集中式部署是指数据集中存放在一个结点上,按应用与数据管理的分工,可分为单用户结构、主机/终端结构(主从式)、客户机/服务器(C/S)结构和浏览器/服务器(B/S)结构。
表7-2 数据库系统部署结构对比
| 部署结构 | 数据存放方式 | 处理分工 | 典型问题 |
|---|---|---|---|
| 单用户结构 | 数据集中在一台计算机 | 应用程序、DBMS和数据库同在一机,由单个用户使用 | 多机之间不能直接共享数据 |
| 主机/终端结构(主从式) | 数据集中在主机 | 主机完成全部处理,终端仅负责输入输出 | 主机易成为性能瓶颈,可靠性要求高 |
| 客户机/服务器结构 | 数据集中在服务器 | 客户端承担界面和部分应用逻辑,服务器承担DBMS和数据管理 | 客户端升级维护成本较高 |
| 浏览器/服务器结构 | 数据集中在服务器 | 客户端仅使用浏览器,应用逻辑集中在应用服务器 | 客户端维护便利,但服务端负担较重 |
这里的“主从式”特指主机集中处理、终端仅负责输入输出的结构,与客户机/服务器结构中客户端具有独立处理能力不同。与主机/终端结构相比,C/S结构将界面和部分应用逻辑交给客户端,实现了应用与数据管理的分离;B/S结构进一步将客户端简化为通用浏览器,可视为C/S结构的一种特例。
2. 分布式部署
分布式部署是指数据在逻辑上属于同一个数据库,在物理上分散存放在通过网络连接的多个结点上。各结点既可独立处理本地数据,也可协同完成全局事务,用户通常无需了解数据的具体存放位置。分布式部署可与上述集中式结构组合使用。
其主要特点如下:
- 数据分片:将一张表按行或按列划分为若干片段,分别存放在不同结点。
- 数据复制:将同一数据在多个结点保存副本,以提高可用性和读取性能。
- 分布透明性:用户无需感知数据的分片、复制及所在位置。
- 本地自治与协同:各结点可独立运行,并通过网络协同处理全局查询与事务。
分布式部署的优点是扩展性好、可靠性高、就近访问速度快,适合物流网络中多仓库、多站点的业务场景。其主要问题是副本间数据一致性维护、分布式事务与并发控制、网络通信开销和系统管理的复杂度较高。
无论采用何种部署模式,现代关系数据库在内部仍需要处理逻辑建模、约束控制、并发访问和数据访问优化等共同问题。
7.4 数据库管理系统
7.4.1 DBMS的主要功能
数据库管理系统是数据库系统的核心软件,其功能主要包括五个方面。一是数据定义,即通过数据定义语言定义模式、外模式、内模式,建立表、视图、索引,并设置完整性和安全性约束;二是数据操纵,即通过数据操纵语言实现查询、插入、修改和删除等基本操作;三是运行控制,即负责事务管理、并发控制、安全控制、完整性检查和恢复控制;四是数据维护,即支持数据的备份、恢复、重组和性能监测;五是数据通信,即支持用户程序与数据库之间的交互,并提供与操作系统、其他DBMS或文件系统之间的数据通信能力。此外,DBMS还需要组织和管理数据字典、用户数据及存取路径。
7.4.2 DBMS的组成
从软件实现角度看,DBMS通常由语言编译处理程序、系统运行控制程序、系统建立与维护程序以及数据字典组成。语言编译处理程序负责处理数据定义语言和数据操纵语言;系统运行控制程序负责并发控制、安全控制、完整性检查、事务管理和缓冲管理;系统建立与维护程序负责数据装入、重组和故障恢复;数据字典则保存三级模式、用户权限和各类系统信息。
不同数据库产品的内部实现差异较大,但目标一致,即在保证正确性的前提下尽可能提高数据访问效率。
7.4.3 DBMS的工作方式
用户请求DBMS访问数据库时,DBMS通常先接收并解析请求,依次检查外模式、外模式/模式映像、模式、模式/内模式映像和存储结构定义,再执行实际存取操作,最后将结果按用户视图格式返回。
对应用开发者而言,DBMS屏蔽了底层存储细节;对数据库管理员而言,DBMS提供了统一的控制入口;对组织管理者而言,DBMS使数据能够作为共享资源持续积累并产生价值。可以说,没有DBMS,就难以形成现代意义上的数据库系统。
7.5 数据模型
7.5.1 数据模型的含义与抽象层次
数据模型是对现实世界数据特征的抽象。它规定了数据的组织形式、数据之间的联系,以及可在这些数据上执行的基本操作和约束规则。一个好的数据模型既要能够反映客观世界,又要便于人理解和在计算机中实现。
按照抽象层次和应用目的,数据模型通常分为概念模型、逻辑数据模型和物理数据模型。
表7-3 数据模型的抽象层次
| 层次 | 面向对象 | 主要任务 | 常见形式 |
|---|---|---|---|
| 概念模型 | 用户和业务人员 | 描述现实世界中的实体、属性和联系 | E-R模型 |
| 逻辑数据模型 | DBMS和数据库设计人员 | 以形式化结构表示数据及其联系 | 层次模型、网状模型、关系模型 |
| 物理数据模型 | 数据库系统实现与运维人员 | 描述存储记录、索引、访问路径等物理组织细节 | DBMS的存储结构定义与配置参数 |
从现实世界到计算机可处理的数据结构,需要经历现实世界、信息世界和计算机世界三个抽象层次,并完成概念建模和逻辑建模两次转换,如图所示。
图7-6 数据模型的两级抽象过程
7.5.2 层次模型与网状模型
层次模型采用树形结构表示实体及其联系,每个子结点通常只有一个双亲结点,适合表示一对多关系。其结构清晰、访问效率较高,但不善于表达多对多联系。
网状模型允许一个结点拥有多个双亲,也允许结点之间存在多种联系,因此比层次模型更贴近现实世界。但其结构复杂、导航性强,应用开发难度较大。
7.5.3 关系模型
关系模型是目前应用最广泛的数据模型。它由E. F. Codd提出,以集合论和谓词逻辑为理论基础,用二维表来表示实体及实体间联系。关系模型的优势在于概念单一、结构清晰、数据独立性强,并易于通过统一的查询语言进行操作。
关系模型建立在严格的集合论基础之上,可以用一张二维表直观理解,表中的每一行称为元组,每一列称为属性,每个属性允许取值的范围称为域。例如,“学生”表中“性别”属性的域就是{男, 女}。从数学上看,设 D1, D2, ..., Dn 是一组域,它们的笛卡儿积就是从每个域中各取一个值组成的所有可能的 n 元组。关系则是这个笛卡儿积中的一个有限子集,即表中实际存在的那些行。
关系模型中的常见术语如下:
- 关系:一张二维表。
- 元组:表中的一行记录。
- 属性:表中的一列。
- 域:属性的取值范围。
- 候选键:能够唯一标识元组且不含多余属性的属性或属性组。
- 主键:从候选键中选出的、用于标识元组的属性或属性组。
- 外键:引用其他关系主键的属性或属性组。
关系数据库中的候选键需要同时满足唯一性和最小性:任意两个不同元组在候选键上的取值不能相同,且候选键中的任一属性都不能删去,否则唯一性将不成立。一个关系可以有多个候选键,但只能选择一个作为主键。包含在任一候选键中的属性称为主属性,不属于任何候选键的属性称为非主属性。
7.5.4 面向对象与新型数据模型
随着复杂数据和大规模网络应用的发展,面向对象数据库、NoSQL数据库、图数据库和向量数据库等新型数据模型不断出现。这些模型适用于特定应用场景,但在高校数据库原理课程中,关系模型仍是最重要的理论主线,因为它在模式设计、完整性约束和规范化理论方面最为成熟。
7.6 数据库设计
数据库设计是数据库课程中最具方法论价值的内容之一。一个数据库系统是否易于扩展、是否便于维护、是否能够稳定反映业务语义,在很大程度上取决于设计阶段的质量。数据库设计不是简单地“画几张表”,而是一个从现实世界抽象出数据结构、约束和联系,并逐步落实为可实现模式的系统过程。
7.6.1 数据库设计的目标与原则
数据库设计的目标是根据应用需求,建立结构合理、冗余可控、约束清晰、性能可接受的数据组织方案。一个良好的数据库设计通常应满足以下原则:
- 语义准确:表、字段和联系应真实反映业务对象及其关系。
- 结构清晰:模式层次分明,命名统一,主外键明确。
- 冗余受控:尽量避免不必要的重复存储。
- 约束完整:关键业务规则应由数据库约束表达。
- 易于扩展:未来新增业务时无需大规模推倒重来。
数据库设计不是单纯追求“表越少越好”或“拆得越细越好”,而是在语义完整性、可维护性和执行效率之间寻找平衡。
7.6.2 数据库设计的基本步骤
从工程过程看,数据库设计通常包括需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施以及数据库运行与维护六个阶段。
(1) 需求分析
需求分析是数据库设计的起点,决定了后续建模是否准确。其核心任务不是立即设计表结构,而是弄清楚系统要管理哪些对象、处理哪些业务、保存哪些数据、支持哪些查询和报表,以及必须遵守哪些业务规则。 以高校选课系统为例,需求分析至少应识别出学生、教师、课程、班级、院系、选课记录和成绩记录等对象;还应明确诸如“一个学生可选多门课程,一门课程可被多个学生选修”“成绩必须依附于选课记录存在”“课程学分必须为正值”等业务规则。
(2) 概念结构设计
概念结构设计是在需求分析基础上,使用概念模型对现实世界进行抽象。最常用的工具是实体-联系模型,即E-R模型。
E-R模型的基本组成如下:
表7-4 E-R模型的基本组成元素
| 元素 | 图形表示 | 含义 |
|---|---|---|
| 实体 | ▭ | 可区分并需要描述的现实对象 |
| 属性 | ⬭ | 实体或联系所具有的特征 |
| 联系 | ◇ | 实体之间存在的业务关联 |
实体可以是学生、供应商、仓库、零件等对象;属性可以是学号、姓名、地址、数量和单价等;联系则描述“学生选修课程”“供应商供应零件”“仓库存放货物”等业务关系。
一个简化的学生选课E-R图表示如下。
- 实体的识别
实体识别的关键在于判断一个对象是否具有独立存在意义、是否有若干可描述属性、是否需要长期保存。在概念设计中,应优先识别核心实体,再考虑辅助实体和联系实体。
例如,在物流库存系统中,仓库、货物、供应商、订单通常是核心实体;而“入库记录”“出库记录”既可以看作业务事件,也可以建模为联系实体,具体取决于系统是否需要保存其时间、数量、经办人等详细属性。
- 属性的确定
属性应满足语义清楚、粒度适中和可维护性强的要求。属性可分为简单属性与复合属性、单值属性与多值属性、存储属性与派生属性等。
例如,“地址”可以视为复合属性,由省、市、区、详细地址组成;“年龄”通常可以由出生日期推导得出,因此更适合作为派生属性而非持久存储字段。
- 联系与联系类型
联系用于表示实体之间的业务语义。根据参与实体数量和基数约束,可分为以下几类:
表7-5 联系类型及示例
| 联系类型 | 含义 | 示例 |
|---|---|---|
| 一对一(1:1) | 一个A实体最多对应一个B实体,反之亦然 | 一个班级对应一个班长 |
| 一对多(1:n) | 一个A实体对应多个B实体,一个B实体只对应一个A实体 | 一个专业包含多个学生 |
| 多对多(m:n) | 一个A实体对应多个B实体,一个B实体也对应多个A实体 | 学生选修多门课程,课程也被多个学生选修 |
| 自联系 | 同一实体内部存在联系 | 员工之间的上下级关系 |
| 多元联系 | 三个及以上实体共同参与一个联系 | 供应商向项目提供零件 |
基数约束是指一个实体的实例在某个联系中可以(或必须)与另一个实体的多少个实例相关联的数量限制,通常表示为1:1、1:n、m:n。基数分析是指根据业务规则,逐一判断联系两端实体的参与数量,从而确定联系类型及参与程度(是否必须参与)的过程。
(3) 逻辑结构设计
逻辑结构设计的任务是把概念模型转换为某一类DBMS支持的数据模型。在关系数据库中,主要工作是将E-R模型转换为关系模式,并确定主键、外键和必要约束。
- 实体到关系模式的转换
通常,一个实体型转换为一个关系模式;实体的属性转换为关系的属性;实体的标识符转换为关系的主键。
例如,学生实体可转换为:
学生(学号, 姓名, 性别, 出生日期, 专业号)
其中“学号”通常作为主键。
- 1:1联系的转换
一对一联系有两种常见处理方式:
- 单独建立一个关系模式。
- 将其中一方主键作为外键合并到另一方关系中。
是否单独建表,通常取决于该联系是否有独立属性、是否有独立生命周期,以及业务上是否需要单独维护。
例如,班级与班长之间若仅表示“谁是班长”,可在班级表中加入班长学号作为外键;若还需要记录任期、任命时间等信息,则更适合建立“班长任职”关系。
- 1:n联系的转换
一对多联系一般通过在n端加入1端主键作为外键来实现;也可以单独建立一个新的关系模式,该关系模式包含两端实体的主键,以n端主键作为该关系的主键,并可附加联系自身的属性。
例如,专业与学生的一对多联系可转换为:
专业(专业号, 专业名称)
学生(学号, 姓名, 专业号)
其中“学生.专业号”是引用“专业.专业号”的外键。
- m:n联系的转换
多对多联系不能直接通过单一外键表示,必须转换为独立的关系模式。该关系模式通常以参与联系各实体的主键组合作为联合主键,并可附加联系自身属性。
例如,学生与课程之间的选课联系应转换为:
学生(学号, 姓名, 专业号)
课程(课程号, 课程名, 学分)
选课(学号, 课程号, 选课时间, 成绩)
其中“选课”是典型的联系关系。其主键通常为“学号 + 课程号”,同时这两个字段也分别作为外键引用学生表和课程表。
- 多元联系的转换
多元联系是三个或三个以上实体共同参与的联系。处理方法通常是为该联系建立单独的关系模式,各参与实体的主键作为外键加入,联系属性作为普通属性加入。该关系模式的主键取决于联系的语义:若同一组参与实体只能发生一次联系,则以各参与实体主键的组合作为主键;若同一组实体之间可多次发生联系(如分多个批次供应),则需要在主键中加入能区分每次联系的属性(如供应日期、供应批次号),或引入独立的代理主键(如供应单号)。
例如,在“供应商-项目-零件”模型中,若同一供应商可多次向同一项目供应同一零件,则可建立:
供应(供应批次号, 供应商号, 项目号, 零件号, 供应量, 供应日期)
其中“供应批次号”为代理主键,“供应商号、项目号、零件号”分别为引用对应实体表的外键。
(4) 物理结构设计
物理结构设计是在逻辑模式基础上进一步落实到存储层,包括数据类型选择、索引建立、存储组织、分区方案和访问路径优化等。物理设计的目标是在不破坏逻辑语义的前提下提升运行效率。
(5) 数据库实施
数据库实施是在逻辑设计和物理设计完成后,在实际DBMS中建立数据库结构、装入数据、进行应用程序编码与调试,并开展试运行的过程。建立数据库结构通常使用数据定义语言创建表、视图、索引和各类约束;数据装载往往需要先对原始数据进行清洗、转换和校验,以保证入库数据符合目标模式。试运行阶段既要检验功能是否满足需求,也要考察响应时间、吞吐量等性能指标。
(6) 数据库运行与维护
数据库投入运行后,仍需要持续维护。运行与维护阶段的主要工作包括维护数据的安全性与完整性、监测并改善数据库性能、执行备份与恢复,以及根据业务变化对数据库进行重组和重构。其中,数据库重组通常只改变物理存储组织,不改变逻辑结构;数据库重构则可能调整模式、增加属性或改变约束。当原有系统已经无法通过局部修改满足新的应用需求时,需要重新进入数据库设计过程。
7.6.3 数据库设计案例
下面以“高校课程管理系统”为例,说明从需求到关系模式的设计过程。
1. 业务需求概述
系统需要完成以下任务:
- 记录学生基本信息、所属专业和入学年份。
- 记录教师基本信息及所属院系。
- 记录课程信息、开课学期和学分。
- 记录学生选课情况和成绩。
- 统计教师授课情况和学生成绩。
2. 概念设计
可识别出以下实体:学生、教师、课程、专业、院系。
可识别出以下联系:
表7-6 高校课程管理系统的主要联系
| 联系 | 类型 | 说明 |
|---|---|---|
| 专业-学生 | 1:n | 一个专业有多个学生 |
| 院系-教师 | 1:n | 一个院系有多个教师 |
| 教师-课程 | 1:1或n:1 | 若一门课固定由一名教师承担则为1:1;若允许多人联合授一门课则为n:1;若同时允许教师教授多门课则为m:n |
| 学生-课程 | m:n | 学生可以选多门课,课程也可被多人选修 |
3. 逻辑设计
若按“一门课程由一位教师任教”的假设,可得如下关系模式:
专业(专业号, 专业名称)
院系(院系号, 院系名称)
教师(工号, 姓名, 职称, 院系号)
学生(学号, 姓名, 性别, 入学年份, 专业号)
课程(课程号, 课程名, 学分, 开课学期, 工号)
选课(学号, 课程号, 成绩, 选课时间)
其中:
- 专业号、院系号、工号、学号、课程号分别作为各自关系的主键。
- 教师表中的院系号是外键。
- 学生表中的专业号是外键。
- 课程表中的工号是外键。
- 选课表中的学号和课程号共同构成主键,并分别作为外键。
若允许“多人联合授课,同时允许教师教授多门课”,则教师与课程之间为m:n联系,此时不能再在课程表中保存工号,而应将该联系单独建为“授课”关系,并去掉课程表中的工号:
课程(课程号, 课程名, 学分, 开课学期)
授课(课程号, 工号, 授课时间, 授课学时)
其中:
- 授课表中的课程号和工号共同构成主键,并分别作为外键,分别引用课程表和教师表。
- 授课时间和授课学时是“教师承担课程”这一联系的属性,不属于教师或课程本身。
- 若同一教师可在不同学期重复讲授同一课程,且开课学期需要区分,则应将开课学期加入授课表并纳入主键。
这一案例说明,数据库设计的关键在于从业务语义出发,而不是机械地把字段堆在一张大表中。
7.6.4 常见问题
数据库设计中存在以下常见的问题应该避免: 1.用报表思维代替数据建模思维。根据某张报表的样子直接设计表结构,导致一张表中混杂多类实体信息。例如,在“学生选课一览表”中同时出现学生姓名、课程名、教师名、教室和成绩,于是便设计出一个包含十几个字段的大表。这样做违背关系建模原则,会导致更新异常和冗余问题。 2.混淆实体属性与联系属性。例如,“成绩”不是学生本身的属性,也不是课程本身的属性,而是“学生选修课程”这一联系的属性。如果把成绩直接放入学生表或课程表,都会破坏语义正确性。
7.7 关系的完整性
7.7.1 完整性的基本含义
完整性是指数据库中数据的正确性、有效性和一致性。正确性强调数据在类型和格式上合法;有效性强调取值处于业务允许的范围;一致性强调表达同一事实的多个数据之间相互协调。关系模型通常从三个层面讨论完整性:实体完整性、参照完整性和用户定义的完整性。
- 实体完整性:保证每个元组都可被唯一标识。
- 参照完整性:保证关系之间的引用是合法的。
- 用户定义的完整性:保证具体业务规则得到满足。
7.7.2 实体完整性
实体完整性要求关系中的主键属性不能取空值。若主键由多个属性组成,则其中任何一个主属性都不能取空值。
例如,在学生关系:
学生(学号, 姓名, 性别, 专业号)
若“学号”是主键,则每个学生元组都必须有非空学号。因为主键是唯一标识元组的依据,主键为空意味着该记录无法被准确区分。
若主键为联合主键,则组成主键的所有属性都必须非空。
例如,在选课关系:
选课(学号, 课程号, 成绩)
若主键为“学号 + 课程号”,则这两个属性均不能为空。因为只有二者共同存在,才能唯一确定某个学生对某门课的一次选课记录。
7.7.3 参照完整性
参照完整性是关系数据库中最具代表性的约束之一,用于保证表与表之间的引用关系合法。
(1) 关系间的引用
在关系模型中,实体间联系通常通过外键体现。例如,学生属于某个专业,可在学生表中设置“专业号”字段引用专业表主键;订单明细属于某张订单,可在明细表中设置“订单号”字段引用订单表主键。
关系间引用示例如下:
专业(专业号, 专业名称)
学生(学号, 姓名, 专业号)
其中“学生.专业号”引用“专业.专业号”。
(2) 外键的定义
设关系R中有属性或属性组F,它与另一关系S的主键相对应,则称F为关系R的外键。R称为参照关系,S称为被参照关系。在一般的一对多联系中,F通常不是R的主键;在多对多联系转换得到的关系中,外键也可能成为复合主键的组成部分。
外键的主要作用有两个:
- 表达实体之间的联系。
- 限制引用值只能来自被参照关系中真实存在的主键值。
(3) 参照完整性的规则
若关系R中的属性F是外键,引用关系S的主键,则R中每个元组在F上的取值必须满足以下条件之一:
- 为空值。
- 等于S中某个元组的主键值。
例如,在学生表中,某个学生的专业号要么为空,表示尚未分配专业;要么必须是专业表中已经存在的某个专业号。若输入一个数据库中根本不存在的专业号,则违反参照完整性。
需要注意的是,允许外键为空是以该外键不参与主键为前提。若外键属性同时属于复合主键,则实体完整性要求其不能为空,此时外键只能取被参照关系中已经存在的主键值。例如,选课表的主键为“学号 + 课程号”,其中两个属性又分别作为外键引用学生和课程,因此二者均不能为空。
(4) 参照完整性案例
(1) 案例一:学生与专业
专业(专业号, 专业名称)
学生(学号, 姓名, 专业号)
若专业表中只有“CS”“IS”“LOG”三个专业号,则学生表中的专业号只能取这三个值或为空,不能任意填写“XX01”。
(2) 案例二:学生、课程与选课
学生(学号, 姓名)
课程(课程号, 课程名)
选课(学号, 课程号, 成绩)
在选课表中,学号必须来自学生表中已存在的学号,课程号必须来自课程表中已存在的课程号。否则,就会出现选课记录引用不存在学生或不存在的课程等语义错误。
(5) 自引用外键
外键也可以引用同一张表,这称为自引用外键。例如,在员工表中设置“上级工号”字段引用本表的工号主键,以表示组织层级结构。
员工(工号, 姓名, 上级工号)
此时,上级工号要么为空,表示最高层管理者;要么必须引用某个已存在员工的工号。
7.7.4 用户定义的完整性
实体完整性和参照完整性属于关系模型中普遍适用的基础规则,但现实业务往往还有大量更具体、更细致的约束,这些约束统称为用户定义的完整性。
用户定义的完整性是针对某一具体应用环境而建立的业务规则。例如,在教学管理中,课程学分必须为正整数,学生成绩必须在0到100之间;在商品管理中,产品价格必须大于0,折后价不得高于原价;在人员管理中,同一身份证号在系统中必须唯一。这些规则不是所有数据库系统都必须具备的普适规则,但对具体业务又至关重要。
(1) 案例一:课程表约束
课程(课程号, 课程名, 学分)
可定义如下规则:课程号不能为空且唯一;课程名不能为空;学分取值在1到6之间;某些课程名在全校范围内不得重复。
(2) 案例二:仓储管理约束
库存(仓库号, 货物号, 数量, 安全库存)
可定义如下规则:库存数量不能为负,安全库存不能为负,数量低于安全库存时允许触发预警,但不一定禁止保存。这里要区分“数据库完整性约束”和“业务预警规则”。前者通常是硬约束,违反时必须拒绝写入;后者则可能属于管理逻辑,可在应用层进一步处理。
7.8 关系模型的规范化
关系规范化理论是数据库原理课程中最核心的理论内容之一。它回答的问题是:如何通过合理分解关系模式,减少数据冗余,避免更新异常,并保持结构清晰。规范化不是机械拆表,而是一套以函数依赖为理论基础、以减少异常为目标的模式优化方法。
7.8.1 规范化的背景与意义
在实际应用中,若把过多信息混合存入同一张表,虽然短期看似方便,但很容易引发以下问题:
- 插入异常:因缺少某些字段值,而无法插入本应存在的信息。
- 删除异常:删除某条记录时,连带丢失其他本应保留的信息。
- 更新异常:同一事实在多处重复存储,修改时容易出现不一致。
- 冗余过高:同一数据反复出现,既浪费存储空间,又增加维护成本。
规范化的目标正是通过分析属性间的依赖关系,拆分出结构更合理的关系模式,使每张表只表达一个相对稳定和清晰的主题。
规范化的核心思想是“按照规则组织数据,通过建立表及其联系来减少冗余与不一致依赖”。规范化不仅是学术概念,也是数据库工程设计中的通用原则。
7.8.2 函数依赖基础
1. 函数依赖的定义
设关系模式为R(U),X和Y是属性集U的子集。若对于R中任意两个元组,只要它们在X上的取值相同,就必然在Y上的取值也相同,则称Y函数依赖于X,记作:
这表示X能够唯一确定Y。
例如,在学生关系中:
含义是:同一个学号一定对应同一个学生姓名、专业号和入学年份。
2. 完全函数依赖与部分函数依赖
若Y依赖于组合键X,且Y不依赖于X的任何真子集,则称Y对X完全函数依赖。若Y只依赖于X的一部分,则称部分函数依赖。
例如,在关系:
选课(学号, 课程号, 学生姓名, 课程名, 成绩)
若主键为“学号 + 课程号”,则:
- 学生姓名只依赖于学号;
- 课程名只依赖于课程号;
- 成绩依赖于学号和课程号的组合。
因此,学生姓名和课程名对联合主键属于部分函数依赖。
3. 传递函数依赖
若:
且Y不是X的子集,Z不是Y的子集,同时不存在 Y → X,则称Z传递函数依赖于X。
例如,在关系:
学生(学号, 姓名, 专业号, 专业名称)
若存在:
则有:
这里专业名称对学号是传递函数依赖。
7.8.3 第一范式(1NF)
定义:如果关系模式中每个属性值都是不可再分的原子值,则称该关系属于第一范式。
第一范式强调的是属性值的原子性,即每个字段中只能保存单一意义的值,而不能在一个字段中塞入一组重复数据或多值集合。
(1) 违反1NF的典型情形
以下设计都不符合第一范式:
- 合并单元格
- 一个字段中存储多个数值,如:“课程号”包含了多个课程号。
- 一个字段中混合保存“省-市-区-详细地址”且系统需要分别处理这些部分。
例如,未规范化的学生选课表可能为:
表7-7 未规范化的学生选课表
| 学号 | 姓名 | 导师办公室 | 课程号 |
|---|---|---|---|
| 1022 | 张三 | 412 | DB01、OS02、NW03 |
| 4123 | 李四 | 216 | DB01、AI05、null |
其中“课程号”包含了多个课程号,不符合第一范式。
转换到第一范式的基本思路是使每个单元格只保存一个原子值。
上表可转换为:
表7-8 满足第一范式的学生选课表
| 学号 | 姓名 | 导师办公室 | 课程号 |
|---|---|---|---|
| 1022 | 张三 | 412 | DB01 |
| 1022 | 张三 | 412 | OS02 |
| 1022 | 张三 | 412 | NW03 |
| 4123 | 李四 | 216 | DB01 |
| 4123 | 李四 | 216 | AI05 |
此时每个字段都保持原子性,因此满足第一范式。
(2) 第一范式的局限性
第一范式只解决“字段是否原子”的问题,并不保证关系中不存在冗余。上表虽然已经满足1NF,但“姓名”和“导师办公室”仍随每个课程重复出现,仍可能发生更新异常。因此,1NF只是规范化的起点,而不是终点。
7.8.4 第二范式(2NF)
定义:若一个关系模式属于第一范式,且所有非主属性都完全函数依赖于每个候选键,则称该关系属于第二范式。
第二范式关注的是:非主属性不能只依赖于联合主键的一部分。
在联合主键关系中,若某些非主属性只依赖于主键的一部分,就会造成明显冗余。
仍以前述1NF关系为例:
选课登记(学号, 课程号, 姓名, 导师办公室)
设主键为“学号 + 课程号”。则有:
“姓名”“导师办公室”不依赖于完整主键,而只依赖于“学号”,因此存在部分函数依赖,不满足第二范式。
要达到第二范式,应将部分函数依赖的属性拆分出去,使每个非主属性都完全依赖于主键。
可分解为两张表:
学生(学号, 姓名, 导师办公室)
选课(学号, 课程号)
分解后:
- 学生姓名和导师办公室只在学生表中出现一次。
- 选课表只保留与选课行为直接相关的信息。
- 当学生选修多门课程时,不再重复存储其姓名和导师办公室。
案例:学生选课系统
假设原始关系为:
成绩登记(学号, 课程号, 学生姓名, 课程名, 学分, 成绩)
主键为“学号 + 课程号”,则存在如下依赖:
其中学生姓名对学号依赖,课程名和学分对课程号依赖,均属于对联合主键的部分函数依赖,因此应分解为:
学生(学号, 学生姓名)
课程(课程号, 课程名, 学分)
选课(学号, 课程号, 成绩)
这是第二范式分析中最常见的示例之一。它说明:若一个关系试图同时表达学生、课程和选课三个主题,就极易出现部分依赖和冗余。
7.8.5 第三范式(3NF)
定义:若一个关系模式属于第二范式,且每一个非主属性都不传递函数依赖于任何候选键,则称该关系属于第三范式。
即使已经消除了部分函数依赖,关系中仍可能存在传递依赖。传递依赖同样会带来冗余和异常。
例如,考虑如下关系:
学生(学号, 姓名, 专业号, 专业名称)
若存在:
则“专业名称”对“学号”属于传递函数依赖,因此该关系不满足第三范式。
应将由非主属性决定的属性独立成表:
学生(学号, 姓名, 专业号)
专业(专业号, 专业名称)
分解后,专业名称不再在每个学生记录中重复出现。这样带来以下优点:
- 新增一个专业时,即使暂时没有学生,也可以先插入专业记录。
- 修改专业名称时,只需改一处。
- 删除某个学生记录时,不会导致专业信息被意外删除。
这正是第三范式解决更新异常、插入异常和删除异常的实际价值所在。
案例:课程安排
考虑关系:
课程安排(课程号, 课程名, 教师号, 教师姓名, 教师办公室)
若主键为课程号,并假设每门课由一位教师授课,则有:
因此:
这是通过教师号产生的传递依赖。因此应分解为:
课程(课程号, 课程名, 教师号)
教师(教师号, 教师姓名, 教师办公室)
这样,教师办公室变更时,只需更新教师表即可。
7.8.6 规范化分解实例
下面给出一个从未规范化表逐步分解到第三范式的完整示例。
1. 原始表
设有如下“学生选课登记表”:
表7-9 学生选课登记表(原始表)
| 学号 | 学生姓名 | 导师 | 导师办公室 | 课程号 | 课程名 | 学分 | 成绩 |
|---|---|---|---|---|---|---|---|
| 202301 | 王敏 | 刘强 | A305 | DB01 | 数据库原理 | 3 | 88 |
| 202301 | 王敏 | 刘强 | A305 | NW02 | 计算机网络 | 3 | 91 |
| 202302 | 张晨 | 赵华 | B210 | DB01 | 数据库原理 | 3 | 84 |
这张表的问题明显:
- 学生姓名、导师、导师办公室重复出现。
- 课程名、学分重复出现。
- 若某门新课程尚无人选修,则无法单独录入课程信息。
- 若删除某学生最后一门课,可能导致其导师信息和课程信息一起丢失。
2. 转换为第一范式
该表已基本具备原子性,因此可视为满足1NF。但仍存在冗余和依赖关系。
3. 分解为第二范式
设原表主键为“学号 + 课程号”,则可识别依赖:
可分解为:
学生(学号, 学生姓名, 导师, 导师办公室)
课程(课程号, 课程名, 学分)
选课(学号, 课程号, 成绩)
此时已消除对联合主键的部分函数依赖。
4. 分解为第三范式
在学生表中仍存在:
从而有:
这是传递依赖,因此继续分解为:
学生(学号, 学生姓名, 导师号)
导师(导师号, 导师姓名, 导师办公室)
课程(课程号, 课程名, 学分)
选课(学号, 课程号, 成绩)
至此,各表主题更单一,依赖关系更清晰,达到第三范式。
7.8.7 规范化目标
在大多数基础应用和通用业务系统中,第三范式已经能够满足设计要求。更高的BCNF要求每个决定因素都包含候选键,用于处理候选键重叠、复合键内部依赖等更特殊的问题;第四范式和第五范式进一步处理多值依赖和连接依赖。规范化并不意味着任何场景都应无条件拆分到最细。现实工程中,为了查询性能、统计便利或历史归档,可能会进行适度反规范化设计,例如保留部分冗余字段或建立汇总表。但反规范化应建立在已经理解规范化原则的基础之上,是有意识的性能权衡,而不是由于设计能力不足造成的结构混乱。
7.8.8 规范化小结
关系规范化可概括为以下递进过程:
表7-10 关系规范化过程总结
| 范式 | 解决的核心问题 | 典型方法 |
|---|---|---|
| 1NF | 消除重复组,保证属性原子性 | 每个字段只保存一个值 |
| 2NF | 消除非主属性对联合主键的部分依赖 | 将部分依赖属性拆分到独立表 |
| 3NF | 消除非主属性对主键的传递依赖 | 将由非主属性决定的属性继续拆分 |
需要明确的是,规范化不是为了“形式好看”,而是为了减少冗余、降低异常、增强可维护性,使数据库结构真正服务于长期稳定的数据管理。
本章小结
本章围绕数据库技术的基本概念、系统结构、数据模型与设计方法展开。首先,数据是信息的载体,数据管理经历了人工管理、文件系统和数据库系统三个阶段,数据库系统在数据共享、冗余控制、独立性和并发控制方面具有明显优势。其次,数据库系统采用外模式、概念模式、内模式三级模式结构,并通过二级映像保证逻辑独立性和物理独立性;数据库管理系统提供数据定义、操纵、控制与维护等功能,DBA负责数据库的规划、运行与安全管理。再次,数据模型由数据结构、数据操作和完整性约束组成,关系模型以二维表表达实体及联系,是目前应用最广泛的模型;实体完整性、参照完整性和用户定义完整性保证数据的正确与一致。最后,数据库设计包括需求分析、概念设计、逻辑设计、物理设计、实施与运行维护等阶段,其中E-R图可转换为关系模式;通过函数依赖分析,将关系逐步规范化到1NF、2NF和3NF,可减少冗余并避免各种异常。实际应用中,应在理解规范化原则的基础上,根据性能需求合理进行反规范化。
课后习题
- 简述数据与信息的区别和联系,并说明数据处理、数据管理与数据库技术之间的关系。
- 比较人工管理阶段、文件系统阶段和数据库系统阶段在数据保存、共享、冗余、独立性和并发控制方面的主要特点。
- 什么是数据库系统的三级模式?外模式、概念模式和内模式分别描述什么内容?二级映像如何保证逻辑独立性和物理独立性?
- 数据模型通常包含哪些组成要素?概念模型、逻辑数据模型和物理数据模型分别解决什么问题?
- 设关系
学生(学号, 姓名, 性别, 出生日期, 专业号),说明什么是域、元组、属性、候选键和主键,并指出学号作为主键时应满足的约束。 - 数据库设计通常分为哪几个阶段?每个阶段的主要任务是什么?
- 某高校系统中,一个学生可以选修多门课程,一门课程可以被多个学生选修,选课记录需要保存成绩。请画出该局部业务的E-R图,并将其转换为关系模式,指出各关系模式的主键和外键。
- 什么是实体完整性、参照完整性和用户定义的完整性?
- 设关系
成绩登记(学号, 课程号, 学生姓名, 课程名, 学分, 成绩),主键为(学号, 课程号)。分析其中存在的函数依赖,说明该关系属于第几范式,并将其逐步分解到3NF。
参考文献
[1] E. F. Codd. A Relational Model of Data for Large Shared Data Banks[J]. Communications of the ACM, 1970, 13(6): 377-387.
[2] 陈志泊. 数据库原理及应用教程(第4版)(微课版)[M]. 北京:人民邮电出版社,2017.
[3] 王珊,萨师煊. 数据库系统概论(第5版)[M]. 北京:高等教育出版社,2014.
[4] Abraham Silberschatz, Henry F. Korth, S. Sudarshan. Database System Concepts[M]. 7th ed. New York: McGraw-Hill Education, 2020.
[5] C. J. Date. An Introduction to Database Systems[M]. 8th ed. Boston: Addison-Wesley, 2004.
[6] Ramez Elmasri, Shamkant B. Navathe. Fundamentals of Database Systems[M]. 7th ed. Boston: Pearson, 2016.
[7] GeeksforGeeks. DBMS Tutorial[EB/OL]. https://www.geeksforgeeks.org/dbms/dbms/.
[8] Microsoft Learn. Explore Fundamental Relational Data Concepts[EB/OL]. https://learn.microsoft.com/en-us/training/modules/explore-relational-data-offerings/.