数据库技术是研究数据库的结构、存储、设计、管理和应用的一门软件学科。数据库系统本质上是一个用计算机存储信息的系统。数据库管理系统是位于用户与操作系统之间的一层数据管理软件,其基本目标是提供一个可以方便、有效地存取数据库信息的环境。数据库就是信息的集合,它是收集计算机数据的仓库或容器,系统用户可以对这些数据执行一系列操作。设计数据库系统的目的是为了管理大量信息,给用户提供数据的抽象视图,即系统隐藏有关数据存储和维护的某些细节。对数据的管理涉及信息存储结构的定义、信息操作机制的提供、安全性保证,以及多用户对数据的共享问题。

本章主要介绍一些数据库的背景知识和基本概念,使读者了解数据库的基本内容,形成数据库系统的总体框架,了解数据库系统在计算机系统中的地位以及数据库系统的功能。

9.1 基本概念

9.1.1 数据库与数据库系统

数据是描述事物的符号记录,它具有多种表现形式,可以是文字、图形、图像、声音和语言等。信息是现实世界事物的存在方式或状态的反映。信息具有可感知、可存储、可加工、可传递和可再生等自然属性,信息已是社会各行各业不可缺少的资源,这也是信息的社会属性。数据是信息的符号表示,而信息是具有特定释义和意义的数据。

数据库系统(DataBase System,DBS)是一个采用了数据库技术,有组织地、动态地存储大量相关数据,方便多用户访问的计算机系统。广义上讲,DBS 是由数据库、硬件、软件和人员组成的。

(1) 数据库(DataBase,DB)。数据库是统一管理的、长期储存在计算机内的、有组织的相关数据的集合。其特点是数据间联系密切、冗余度小、独立性较高、易扩展,并且可为各类用户共享。

(2) 硬件。硬件是构成计算机系统的各种物理设备,包括存储数据所需的外部设备。硬件的配置应满足整个数据库系统的需要。

(3) 软件。软件包括操作系统、数据库管理系统及应用程序。数据库管理系统简称 DBMS,它是数据库系统的核心软件,需要在操作系统的支持下工作,解决如何科学地组织和储存数据,如何高效地获取和维护数据。其主要功能包括数据定义功能、数据操纵功能、数据库的运行管理和数据库的建立与维护。

(4) 人员。人员主要有4类。第一类为系统分析员和数据库设计人员,系统分析员负责应用系统的需求分析和规范说明,他们和用户及数据库管理员一起确定系统的硬件配置,并参与数据库系统的概要设计;数据库设计人员负责数据库中数据的确定、数据库各级模式的设计。第二类为应用程序员,负责编写使用数据库的应用程序,这些应用程序可对数据进行检索、建立、删除或修改。第三类为最终用户,他们应用系统的接口或利用查询语言访问数据库。第四类用户是数据库管理员(Data Base Administrator,DBA),负责数据库的总体信息控制。DBA 的具体职责包括决定数据库中的信息内容和结构;决定数据库的存储结构和存取策略;定义数据库的安全性要求和完整性约束条件;监控数据库的使用和运行;改进数据库的性能;重组和重构数据库,以提高系统的性能。

9.1.2 数据库管理系统的功能

数据库管理系统(DataBase Management System,DBMS)主要实现对共享数据有效地组织、管理和存取,故 DBMS 应具有以下六个方面的功能。

1. 数据定义

DBMS 提供数据定义语言(Data Definition Language,DDL),用户可以对数据库的结构进行描述,包括外模式、模式和内模式的定义;数据库的完整性定义;安全保密定义,如口令、级别和存取权限等。这些定义存储在数据字典中,是 DBMS 运行的基本依据。

2. 数据库操作

DBMS 向用户提供数据操纵语言(Data Manipulation Language,DML),实现对数据库中数据的基本操作,例如检索、插入、修改和删除。DML分为两类,即宿主型和自含型。所谓宿主型是指将 DML 语句嵌入某种主语言(如 C、COBOL 等)中使用;自含型是指可以单独使用 DML 语句,供用户交互使用。

3. 数据库运行管理

数据库在运行期间多用户环境下的并发控制、安全性检查和存取控制、完整性检查和执行、运行日志的组织管理、事务管理和自动恢复等是 DBMS 的重要组成部分,这些功能可以保证数据库系统的正常运行。

4. 数据的组织、存储和管理

DBMS 分类组织、存储和管理各种数据,包括数据字典、用户数据和存取路径等。因此要确定以何种文件结构和存取方式在存储级上组织这些数据,以提高存取效率。实现数据间的联系、数据组织和存储的基本目标是提高存储空间的利用率。

5. 数据库的建立和维护

数据库的建立和维护包括数据库的初始建立、数据的转换、数据库的转储和恢复、数据库的重组和重构、性能监测和分析等。

6. 其他功能

其他功能包括:DBMS 的网络通信功能,一个 DBMS 与另一个 DBMAS 或文件系统的数据转换功能,异构数据库之间的互访和互操作能力等。

9.1.3 数据库管理系统的特征及分类

1. DBMS 的特征

通过 DBMS 来管理数据具有以下特点。

(1) 数据结构化且统一管理。数据库中的数据由 DBMS 统一管理。由于数据库系统采用复杂的数据模型表示数据结构,数据模型不仅描述数据本身的特点,还描述数据之间的联系。数据不再面向某个应用,而是面向整个应用系统。数据易维护、易扩展,数据冗余明显减少,真正实现了数据的共享。

(2) 有较高的数据独立性。数据的独立性是指数据与程序独立,将数据的定义从程序中分离出去,由 DBMS 负责数据的存储,应用程序关心的只是数据的逻辑结构,无须了解数据在磁盘上的数据库中的存储形式,从而简化应用程序,大大减少了应用程序编制的工作量。数据的独立性包括数据的物理独立性和数据的逻辑独立性。

(3) 数据控制功能。DBMS 提供了数据控制功能,以适应共享数据的环境。数据控制功能包括对数据库中数据的安全性、完整性、并发和恢复的控制。

① 数据库的安全性。数据库的安全性(Security)是指保护数据库以防止不合法的使用所造成的数据泄漏、更改或破坏。这样,用户只能按规定对数据进行处理,例如,划分了不同的权限,有的用户只能有读数据的权限,有的用户有修改数据的权限,用户只能在规定的权限范围内操纵数据库。

② 数据的完整性。数据库的完整性是指数据库的正确性和相容性,是防止合法用户使用数据库时向数据库加入不符合语义的数据,保证数据库中的数据是正确的,避免非法的更新。

③ 并发控制。在多用户共享的系统中,许多用户可能同时对同一数据进行操作。DBMS 的并发控制子系统负责协调并发事务的执行,保证数据库的完整性不受破坏,避免用户得到不正确的数据。

④ 故障恢复。数据库中的4类故障是事务内部故障、系统故障、介质故障及计算机病毒。故障恢复主要指恢复数据库本身,即在故障引起数据库当前状态不一致时将数据库恢复到某个正确状态或一致状态。恢复的原理非常简单,就是要建立冗余(Redundancy)数据。换句话说,确定数据库是否可恢复的方法就是其包含的每一条信息是否都可以利用冗余存储在别处的信息重构。冗余是物理级的,通常认为逻辑级是没有冗余的。

2. DBMS 的分类

DBMS 通常可分为以下三类。

(1) 关系数据库系统(Relation DataBase Systems,RDBS)。关系数据库系统是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据。目前主流的关系数据库有 Oracle、Db2、Sybase、Microsoft SQL Server、Microsoft Access、MySQL 等。在关系模型中,实体以及实体间的联系都是用关系来表示的。在一个给定的现实世界领域中,相应的所有实体及实体之间联系的关系的集合构成一个关系数据库,也有型和值之分。关系数据库的型也称为关系数据库模式,它是对关系数据库的描述,是关系模式的集合。关系数据库的值也称为关系数据库,是关系的集合。关系数据库模式与关系数据库通常统称为关系数据库。

(2) 面向对象的数据库系统(Object-Oriented DataBase System,OODBS)。面向对象的数据库系统是支持以对象形式对数据建模的数据库管理系统,包括对对象的类、类属性的继承和子类的支持。面向对象数据库系统主要有两个特点:一是面向对象数据模型能完整地描述现实世界的数据结构,能表达数据间的嵌套、递归联系;二是具有面向对象技术的封装性和继承性提高了软件的可重用性。

(3) 对象关系数据库系统(Object-Oriented Relation DataBase System,ORDBS)。对象关系数据库系统是在传统的关系数据模型基础上提供元组、数组、集合等更为丰富的数据类型以及处理新的数据类型操作的能力,这样形成的数据模型被称为”对象关系数据模型”,基于对象关系数据模型的 DBS 称为对象关系数据库系统。

9.1.4 数据库系统的体系结构

数据库系统是数据密集型应用的核心,其体系结构受数据库运行所在的计算机系统的影响很大,尤其是受计算机体系结构中的连网、并行和分布的影响。从不同的角度或不同层次上看,数据库系统体系结构不同;从最终用户的角度看,数据库系统体系结构分为集中式、分布式、C/S(客户端/服务器)和并行结构;从数据库管理系统的角度看,数据库系统体系结构一般采用三级模式结构。

1. 集中式数据库系统

分时系统环境下的集中式数据库系统结构诞生于20世纪60年代中期。当时的硬件和操作系统决定了分时系统环境下的集中式数据库系统结构成为早期数据库技术的首选结构。在这种系统中,不仅数据是集中的,数据的管理也是集中的,数据库系统的所有功能(从形式的用户接口到 DBMS 核心)都集中在 DBMS 所在的计算机上,如图9-1所示。大多数关系 DBMS 的产品也是从这种系统结构开始发展的,目前这种系统还在使用。

2. 客户端/服务器结构

随着网络技术的迅猛发展,很多现代软件都采用客户端/服务器体系结构,如图9-2所示。在这种结构中,一个处理机(客户端)的请求被送到另一个处理机(服务器)上执行。其主要特点是客户端与服务器 CPU 之间的职责明确,客户端主要负责数据表示服务,服务器主要负责数据库服务。采用客户端/服务器结构后,数据库系统功能分为前端和后端。前端主要包括图形用户界面、表格生成和报表处理等工具;后端负责存取结构、查询计算和优化、并发控制以及故障恢复等。前端与后端通过 SQL 或应用程序来接口。ODBC(开放式数据库互连)和 JDBC(Java 程序数据库连接)标准定义了应用程序和数据库服务器通信的方法,即定义了应用程序接口,应用程序用它来打开与数据库的连接、发送查询和更新以及获取返回结果等。

数据库服务器一般可分为事务服务器和数据服务器。

(1) 事务服务器。事务服务器也称查询服务器。它提供一个接口,使得客户端可以发出执行一个动作的请求,服务器响应客户端请求,并将执行结果返回给客户端。用户端可以用 SQL,也可以通过应用程序或使用远程过程调用机制来表达请求。一个典型的事务服务器系统包括多个在共享内存中访问数据的进程,包括服务器进程、锁管理进程、写进程、监视进程和检查点进程。

(2) 数据服务器。数据服务器系统使得客户端可以与服务器交互,以文件或页面为单位对数据进行读取或更新。数据服务器与文件服务器相比提供更强的功能,所支持的数据单位可以比文件还要小,如页、元组或对象;提供数据的索引机制和事务机制,使得客户端或进程发生故障时数据也不会处于不一致状态。

3. 并行数据库系统

并行体系结构的数据库系统是多个物理上连在一起的 CPU,而分布式系统是多个地理上分开的 CPU。并行体系结构的数据库类型分为共享内存式多处理器和无共享式并行体系结构。

1) 共享内存式多处理器

共享内存式多处理器是指一台计算机上同时有多个活动的 CPU,它们共享单个内存和一个公共磁盘接口,如图9-3所示。这种并行体系结构最接近于传统的单 CPU 处理器结构,其设计的主要挑战是用 $N$ 个 CPU 来得到 $N$ 倍单 CPU 的性能。但是,由于不同的 CPU 对公共内存的访问是平等的,这样可能会导致一个 CPU 访问的数据被另一个 CPU 修改,所以必须要有特殊的处理。然而,由于内存访问采用的是一种高速机制,这种机制很难保证进行内存划分时不损失效率,所以这些共享内存访问问题会随着 CPU 个数的增加变得难以解决。

2) 无共享式并行体系结构

无共享式并行体系结构是指一台计算机上同时有多个活动的 CPU,并且它们都有自己的内存和磁盘,如图9-4所示,图中粗线表示高速网络。在不产生混淆的情况下,该结构的数据库系统也称为并行数据库系统。各个承担数据库服务责任的 CPU 划分它们自身的数据,通过划分的任务以及通过每秒兆位级的高速网络通信完成事务查询。

4. 分布式数据库系统

分布式 DBMS 包括物理上分布、逻辑上集中的分布式数据库结构和物理上分布、逻辑上分布的分布式数据库结构两种。前者的指导思想是把单位的数据模式(称为全局数据模式)按数据来源和用途合理地分布在系统的多个结点上,使大部分数据可以就地或就近存取。数据在物理上分布后,由系统统一管理,使用户不感到数据的分布。后者一般由两部分组成:一是本结点的数据模式,二是本结点共享的其他结点上有关的数据模式。结点间的数据共享由双方协商确定。这种数据库结构有利于数据库的集成、扩展和重新配置。

9.1.5 数据库的三级模式结构

实际上,数据库的产品很多,它们支持不同的数据模型,使用不同的数据库语言,建立在不同的操作系统上。数据的存储结构也各不相同,但体系结构基本上都具有相同的特征,采用”三级模式和两级映像”,如图9-5所示。

数据库系统采用三级模式结构,这是数据库管理系统内部的系统结构。数据库有”型”和”值”的概念,”型”是指对某一数据的结构和属性的说明,”值”是型的一个具体赋值。

数据库系统设计员可以在视图层、逻辑层和物理层对数据进行抽象,通过外模式、概念模式和内模式来描述不同层次上的数据特性。

1. 概念模式

概念模式也称模式,它是数据库中全部数据的逻辑结构和特征的描述,由若干个概念记录类型组成,只涉及型的描述,不涉及具体的值。概念模式的一个具体值称为模式的一个实例,同一个模式可以有很多实例。

概念模式反映的是数据库的结构及其联系,所以是相对稳定的;而实例反映的是数据库某一时刻的状态,所以是相对变动的。

需要说明的是,概念模式不仅要描述概念记录类型,还要描述记录间的联系、操作以及数据的完整性和安全性等要求。但是,概念模式不涉及存储结构、访问技术等细节。只有这样,概念模式才算做到了”物理数据独立性”。

描述概念模式的数据定义语言称为”模式 DDL(Schema Data Definition Language)”。

2. 外模式

外模式也称用户模式或子模式,是用户与数据库系统的接口,是用户用到的那部分数据的描述。它由若干个外部记录类型组成。用户使用数据操纵语言对数据库进行操作,实际上是对外模式的外部记录进行操作。

描述外模式的数据定义语言称为”外模式 DDL”。有了外模式后,程序员不必关心概念模式,只与外模式发生联系,按外模式的结构存储和操纵数据。

3. 内模式

内模式也称存储模式,是数据物理结构和存储方式的描述,是数据在数据库内部的表示方式,定义所有的内部记录类型、索引和文件的组织方式,以及数据控制方面的细节。例如,记录的存储方式是顺序存储,按照 B 树结构存储,还是 Hash 方法存储;索引按照什么方式组织;数据是否压缩存储,是否加密;数据的存储记录结构有何规定。

描述内模式的数据定义语言称为”内模式 DDL”。

注意,内部记录并不涉及物理记录,也不涉及设备的约束。它比内模式更接近于物理存储和访问的那些软件机制,是操作系统的一部分(即文件系统)。例如,从磁盘上读、写数据。

总之,数据按外模式的描述提供给用户,按内模式的描述存储在磁盘上,而概念模式提供了连接这两级模式的相对稳定的中间层,并使得两级中任意一级的改变都不受另一级影响。

4. 两级映像

数据库系统在三级模式之间提供了两级映像:模式/内模式映像、外模式/模式映像。正因为这两级映像保证了数据库中的数据具有较高的逻辑独立性和物理独立性。

(1) 模式/内模式映像。存在于概念级和内部级之间,实现了概念模式和内模式之间的相互转换。

(2) 外模式/模式映像。存在于外部级和概念级之间,实现了外模式和概念模式之间的相互转换。

数据的独立性是指数据与程序独立,将数据的定义从程序中分离出去,由 DBMS 负责数据的存储,从而简化应用程序,大大减少应用程序编制的工作量。数据的独立性是由 DBMS 的二级映像功能来保证的。数据的独立性包括数据的物理独立性和数据的逻辑独立性。

(1) 数据的物理独立性。数据的物理独立性是指当数据库的内模式发生改变时,数据的逻辑结构不变。由于应用程序处理的只是数据的逻辑结构,这样物理独立性可以保证,当数据的物理结构改变时,应用程序不用改变。但是,为了保证应用程序能够正确执行,需要修改概念模式和内模式之间的映像。

(2) 数据的逻辑独立性。数据的逻辑独立性是指用户的应用程序与数据库的逻辑结构是相互独立的。数据的逻辑结构发生变化后,用户程序也可以不修改。但是,为了保证应用程序能够正确执行,需要修改外模式和概念模式之间的映像。

9.1.6 大数据

1. 大数据产生的背景

大数据(Big Data)是指”无法用现有的软件工具提取、存储、搜索、共享、分析和处理的海量的、复杂的数据集合”。大数据产生的背景主要有以下4个方面。

(1) 数据来源和承载方式的变革。由于物联网、云计算、移动互联网等新技术的发展,用户在线的每一次点击、每一次评论、每一个视频点播,都是大数据的典型来源;而遍布地球各个角落的手机、PC、平板电脑及传感器成为数据来源和承载方式。可见,只有大连接与大交互,才有大数据。

(2) 全球数据量出现爆炸式增长。由于视频监控、智能终端、网络商店等快速普及,使得全球数据量出现爆炸式增长。许多研究表明,未来数年数据量会呈现指数增长。根据麦肯锡全球研究院(MGI)估计,全球企业2010年在硬盘上存储了超过7EB($1\text{EB}$ 等于 $10^9\text{GB}$)的新数据,而消费者在 PC 和笔记本等设备上存储了超过6EB的新数据。据 IDC(Internet Data Center)预测,到2020年,全球以电子形式存储的数据量将达32ZB。

(3) 大数据已经成为一种自然资源。许多研究者认为:大数据是”未来的新石油”,已成为一种新的经济资产类别。一个国家拥有数据的规模、活性及解释运用的能力将成为综合国力的重要组成部分。

(4) 大数据日益重要,不被利用就是成本。大数据作为一种数据资产当仁不让地成为现代商业社会的核心竞争力,不被利用就是企业的成本。因为,数据资产可以帮助和指导企业对整个业务流程进行有效的运营和优化,帮助企业做出最明智的决策。

2. 大数据的特征

大数据(Big Data)是指”无法用现有的软件工具提取、存储、搜索、共享、分析和处理的海量的、复杂的数据集合”。业界通常用”4V”来概括大数据的特征。

大量化(Volume)指数据体量巨大。随着 IT 技术的迅猛发展,数据量级已从 TB($10^{12}$ 字节)发展至 PB 乃至 ZB,可称海量、巨量乃至超量。当前,典型个人计算机硬盘的容量为 TB 量级,而一些大企业的数据量已经接近 EB 量级。

多样化(Variety)指数据类型繁多。相对于以往便于存储的以文本为主的结构化数据,非结构化数据越来越多,包括网络日志、音频、视频、图片、地理位置信息等,这些多类型的数据对数据的处理能力提出了更高的要求。

价值密度低(Value)指大量的不相关信息导致价值密度的高低与数据总量的大小成反比。以视频为例,一部一小时的视频,在连续不间断的监控中,有用数据可能仅有一两秒。因此,如何通过强大的机器算法更迅速地完成数据的价值”提纯”,如何对未来趋势与模式的可预测分析、深度复杂分析(机器学习、人工智能 VS 传统商务智能咨询、报告等),成为目前大数据背景下亟待解决的难题。

快速化(Velocity)指处理速度快。大数据时代对时效性要求很高,这是大数据区分于传统数据挖掘的最显著特征。因为,在大数据环境下数据流通常为高速实时数据流,而且需要快速、持续的实时处理;处理工具也在快速演进,软件工程及人工智能等均可能介入。

3. 理解大数据

大数据不仅仅是指海量的信息,更强调人类对信息的筛选、处理,保留有价值的信息,即让大数据更有意义,挖掘其潜在的”大价值”这才是对大数据的正确理解。为此,有许多问题需要研究与解决。

(1) 高并发数据存取的性能要求及数据存储的横向扩展问题。目前,多从架构和并行等方面考虑解决。

(2) 实现大数据资源化、知识化、普适化的问题,解决这些问题的关键是对非结构化数据的内容理解。

(3) 非结构化海量信息的智能化处理问题,主要解决自然语言理解、多媒体内容理解、机器学习等问题。

大数据时代主要面临三大挑战:软件和数据处理能力、资源和共享管理以及数据处理的可信力。

(1) 软件和数据处理能力。应用大数据技术,提升服务能力和运作效率,以及个性化的服务,比如医疗、卫生、教育等部门。

(2) 资源和共享管理。应用大数据技术,提高应急处置能力和安全防范能力。

(3) 数据处理的可信力。需要投资建立大数据的处理分析平台,实现综合治理、业务开拓等目标。

4. 大数据产生的安全风险

2012年瑞士达沃斯论坛上发布的《大数据大影响》报告称,数据已成为一种新的经济资产类别,就像货币或黄金一样。因此,也带来了更多安全风险。

(1) 大数据成为网络攻击的显著目标。在互联网环境下,大数据是更容易被”发现”的大目标。这些数据会吸引更多的潜在攻击者,如数据的大量汇集,使得黑客成功攻击一次就能获得更多数据,无形中降低了黑客的攻击成本,增加了”收益率”。

(2) 大数据加大了隐私泄露风险。大量数据的汇集不可避免地加大了用户隐私泄露的风险,因为数据集中存储增加了泄露风险;另外,一些敏感数据的所有权和使用权并没有明确界定,很多基于大数据的分析都未考虑到其中涉及的个体隐私问题。

(3) 大数据威胁现有的存储和安防措施。大数据存储带来新的安全问题,数据大集中的后果是复杂多样的数据存储在一起,很可能出现将某些生产数据放在经营数据存储位置的情况,致使企业安全管理不合规。大数据的大小也影响到安全控制措施能否正确运行。如果安全防护手段的更新升级速度无法跟上数据量非线性增长的步伐,就会暴露大数据安全防护的漏洞。

(4) 大数据技术成为黑客的攻击手段。在企业用数据挖掘和数据分析等大数据技术获取商业价值的同时,黑客也在利用这些大数据技术向企业发起攻击。黑客会最大限度地收集更多的有用信息,例如社交网络、邮件、微博、电子商务、电话和家庭住址等信息,大数据分析使黑客的攻击更加精准。

(5) 大数据成为高级可持续攻击的载体。传统的检测是基于单个时间点进行的基于威胁特征的实时匹配检测,而高级可持续攻击(APT)是一个实施过程,无法被实时检测。此外,大数据的价值低密度性使得安全分析工具很难聚焦在价值点上,黑客可以将攻击隐藏在大数据中,给安全服务提供商的分析制造很大困难。黑客设置的任何一个会误导安全厂商目标信息提取和检索的攻击,都会导致安全监测偏离应有方向。

(6) 大数据技术为信息安全提供新支撑。当然,大数据也为信息安全的发展提供了新机遇。大数据正在为安全分析提供新的可能性,对于海量数据的分析有助于信息安全服务提供商更好地刻画网络异常行为,从而找出数据中的风险点。对实时安全和商务数据结合在一起的数据进行预防性分析,可识别钓鱼攻击,防止诈骗和阻止黑客入侵。网络攻击行为总会留下蛛丝马迹,这些痕迹都以数据的形式隐藏在大数据中,利用大数据技术整合计算和处理资源有助于更有针对性地应对信息安全威胁,有助于找到攻击的源头。

9.2 数据模型

9.2.1 基本概念

模型就是对现实世界特征的模拟和抽象,数据模型是对现实世界数据特征的抽象。对于具体的模型人们并不陌生,如航模飞机、地图和建筑设计沙盘等都是具体的模型。最常用的数据模型分为概念数据模型和基本数据模型。

(1) 概念数据模型。概念数据模型也称信息模型,是按用户的观点对数据和信息建模;是现实世界到信息世界的第一层抽象,强调其语义表达功能,易于用户理解;是用户和数据库设计人员交流的语言,主要用于数据库设计。这类模型中最著名的是实体-联系模型,简称 E-R 模型。

(2) 基本数据模型。它是按计算机系统的观点对数据建模,是现实世界数据特征的抽象,用于 DBMS 的实现。基本的数据模型有层次模型、网状模型、关系模型和面向对象模型(Object Oriented Model)。

9.2.2 数据模型的三要素

数据库结构的基础是数据模型,是用来描述数据的一组概念和定义。数据模型的三要素是数据结构、数据操作和数据的约束条件。

(1) 数据结构。数据结构是所研究的对象类型的集合,是对系统静态特性的描述。

(2) 数据操作。数据操作是对数据库中各种对象(型)的实例(值)允许执行的操作的集合,包括操作及操作规则。例如操作有检索、插入、删除和修改,操作规则有优先级别等。数据操作是对系统动态特性的描述。

(3) 数据的约束条件。数据的约束条件是一组完整性规则的集合。也就是说,对于具体的应用数据必须遵循特定的语义约束条件,以保证数据的正确、有效和相容。例如某单位人事管理中,要求在职的”男”职工的年龄必须大于18岁小于60,工程师的基本工资不能低于1500元,每个职工可担任一个工种,这些要求可以通过建立数据的约束条件来实现。

9.2.3 E-R 模型

概念模型是对信息世界建模,所以概念模型能够方便、准确地表示信息世界中的常用概念。概念模型有很多种表示方法,其中最为常用的是 P.P.S.Chen 于1976年提出的实体-联系方法(Entity Relationship Approach)。该方法用 E-R 图来描述现实世界的概念模型,称为实体-联系模型(Entity-Relationship Model,E-R 模型)。

E-R 模型是软件工程设计中的一个重要方法,因为它接近于人的思维方式,容易理解并且

与计算机无关,所以用户容易接受,是用户和数据库设计人员交流的语言。但是,E-R 模型只能说明实体间的语义联系,还不能进一步地详细说明数据结构。在解决实际应用问题时,通常先设计一个 E-R 模型,然后再把其转换成计算机能接受的数据模型。

1. 实体

在 E-R 模型中,实体用矩形表示,通常矩形框内写明实体名。实体是现实世界中可以区别于其他对象的”事件”或”物体”。例如,企业中的每个人都是一个实体。每个实体由一组特性(属性)来表示,其中的某一部分属性可以唯一标识实体,例如职工实体集中的职工号。实体集是具有相同属性的实体集合。例如,学校的所有教师具有相同的属性,因此教师的集合可以定义为一个实体集;学生具有相同的属性,因此学生的集合可以定义为另一个实体集。

2. 联系

在 E-R 模型中,联系用菱形表示,通常菱形框内写明联系名,并用无向边分别与有关实体连接起来,同时在无向边旁标注上联系的类型($1:1$、$1:n$ 或 $m:n$)。实体的联系分为实体内部的联系和实体与实体之间的联系。实体内部的联系反映数据在同一记录内部各字段间的联系。

1)两个不同实体之间的联系

两个不同实体集之间存在以下3种联系类型。

  • 一对一($1:1$)。指实体集 $E_1$ 中的一个实体最多只与实体集 $E_2$ 中的一个实体相联系。
  • 一对多($1:n$)。表示实体集 $E_1$ 中的一个实体可与实体集 $E_2$ 中的多个实体相联系。
  • 多对多($m:n$)。表示实体集 $E_1$ 中的多个实体可与实体集 $E_2$ 中的多个实体相联系。

例如,图9-6表示两个不同实体集之间的联系。其中:

(1)电影院里一个座位只能坐一个观众,因此观众与座位之间是一个 $1:1$ 的联系,联系名为 V_S,用 E-R 图表示如图9-6(a)所示。

(2)部门 DEPT 和职工 EMP 实体集,若一个职工只能属于一个部门,那么这两个实体集之间应是一个 $1:n$ 的联系,联系名为 D_E,用 E-R 图表示如图9-6(b)所示。

(3)工程项目 PROJ 和职工 EMP 实体集,若一个职工可以参加多个项目,一个项目可以有多个职工参加,那么这两个实体集之间应是一个 $m:n$ 的联系,联系名为 PR_E,用 E-R 图表示如图9-6(c)所示。

2)两个以上不同实体集之间的联系

两个以上不同实体集之间存在 $1:1:1$、$1:1:n$、$1:m:n$ 和 $r:m:n$ 的联系。例如,图9-7表示了3个不同实体集之间的联系。其中:

(1)图9-7(a)表示供应商 Supp、项目 Proj 和零件 Part 之间多对多对多($r:n:m$)的联系,联系名为 SP_P。表示供应商为多个项目供应多种零件,每个项目可用多个供应商供应的零件,每种零件可由不同的供应商供应的语义。

(2)图9-7(b)表示病房、病人和医生之间一对多对多($1:n:m$)的联系,联系名为 P_D。表示一个特护病房有多个病人和多个医生,一个医生只负责一个病房,一个病人只属于一个病房的语义。

注意,3个实体集之间的多对多联系和3个实体集两两之间的多对多联系的语义是不同的。例如,供应商和项目实体集之间的”合同”联系,表示供应商为哪几个工程签了合同;供应商与零件两个实体集之间的”库存”联系,表示供应商库存零件的数量;项目与零件两个实体集之间的”组成”联系,表示一个项目由哪几种零件组成。

3)同一实体集内的二元联系

同一实体集内的各实体之间也存在 $1:1$、$1:n$ 和 $m:n$ 的联系,如图9-8所示。

从图中可知,职工实体集中的领导与被领导的联系是 $1:n$ 的。但是,职工实体集中的婚姻联系是 $1:1$ 的。

3. 属性

属性是实体某方面的特性。例如,职工实体集具有职工号、姓名、年龄、参加工作时间和通信地址等属性。每个属性都有其取值范围,例如职工号为 000001~999999 的6位整型数,姓名为10位的字符串,年龄的取值范围为 18~60 等。在同一实体集中,每个实体的属性及其域是相同的,但可能取不同的值。E-R 模型中的属性有以下分类。

(1)简单属性和复合属性。简单属性是原子的、不可再分的,复合属性可以细分为更小的部分(即划分为别的属性)。有时用户希望访问整个属性,有时希望访问属性的某个成分,那么在模式设计时可采用复合属性。例如,职工实体集的通信地址可以进一步分为邮编、省、市、街道。若不特别声明,通常指的是简单属性。

(2)单值属性和多值属性。在前面所举的例子中,定义的属性对于一个特定的实体都只有单独的一个值。例如,对于一个特定的职工,只对应一个职工号、职工姓名,这样的属性称为单值属性。但是,在某些特定情况下,一个属性可能对应一组值。例如,职工可能有0个、1个或多个亲属,那么职工的亲属的姓名可能有多个数目,这样的属性称为多值属性。

(3)NULL 属性。当实体在某个属性上没有值或属性值未知时,使用 NULL 值,表示无意义或不知道。

(4)派生属性。派生属性可以从其他属性得来。例如,职工实体集中有”参加工作时间”和”工作年限”属性,那么”工作年限”的值可以由当前时间和参加工作时间得到。这里,”工作年限”就是一个派生属性。

4. 实体-联系方法

概念模型中最常用的方法为实体-联系方法,简称 E-R 方法。该方法直接从现实世界中抽象出实体和实体间的联系,然后用非常直观的 E-R 图来表示数据模型。在 E-R 图中有如表9-1所示的几个主要构件。

表9-1 E-R图中的主要构件

构件 说明
矩形 表示实体集
双边矩形 表示弱实体集
菱形 表示联系集
双边菱形 表示弱实体集对应的标识性联系
椭圆 表示属性
线段 将属性与相关的实体集连接,或将实体集与联系集相连
双椭圆 表示多值属性
虚椭圆 表示派生属性
双线 表示一个实体全部参与到联系集中

说明1:在 E-R 图中,实体集中作为主码的一部分属性以下划线标明。另外,在实体集与联系的线段上标上联系的类型。

说明2:在本书中,若不引起误解,实体集有时简称实体,联系集有时简称联系。

【例 9.1】学校有若干个系,每个系有若干名教师和学生;每个教师可以担任若干门课程,并参加多个项目;每个学生可以同时选修多门课程。请设计该学校教学管理系统的 E-R 模型,要求给出每个实体、联系的属性。

解:该学校教学管理系统的 E-R 模型应该有5个实体,即系、教师、学生、项目和课程。

(1)设计各实体属性如下:

  • 系(系号,系名,主任名)
  • 教师(教师号,教师名,职称)
  • 学生(学号,姓名,年龄,性别)
  • 项目(项目号,名称,负责人)
  • 课程(课程号,课程名,学分)

(2)各实体之间的联系如下:

教师担任课程的 $1:n$ “任课”联系;教师参加项目的 $n:m$ “参加”联系;学生选修课程的 $n:m$ “选修”联系;教师、学生与系之间所属关系的 $1:n:m$ “领导”联系。其中,”参加”联系有一个排名属性,”选修”联系有一个成绩属性。

通过上述分析,该学校教学管理系统的 E-R 模型如图9-9所示。

需要特别指出的是,E-R 模型强调的是语义,与现实世界的问题密切相关。这句话的意思是,尽管都是学校教学管理,但由于不同的学校教学管理的方法可能会有不同的语义,因此会得到不同的 E-R 模型。

5. 扩充的 E-R 模型

尽管基本的 E-R 模型足以对大多数数据库特征建模,但数据库某些情况下的特殊语义仅用基本 E-R 模型无法表达清楚。在这一节中将讨论扩充的 E-R 模型,包括弱实体、特殊化、普遍化等概念。

1)弱实体

在现实世界中有一种特殊的联系,这种联系代表实体间的所有(Ownership)关系,例如职工与家属的联系,家属总是属于某职工的。这种实体对于另一些实体具有很强的依赖关系,即一个实体的存在必须以另一个实体为前提,将这类实体称为弱实体。

在扩展的 E-R 图中,弱实体用双线矩形框表示。图9-10为职工与家属的 E-R 图。

2)特殊化

前面已经介绍,实体集是具有相同属性的实体集合。但在现实世界中,某些实体一方面具有一些共性,另一方面还具有各自的特殊性。这样,一个实体集可以按照某些特征区分为几个子实体。例如,学生实体集可以分为研究生、本科生和大专生等子集。将这种从普遍到特殊的过程称为”特殊化”。

将几个具有共同特性的实体集概括成一个更普遍的实体集的过程称为”普遍化”。例如,可以将大专生、本科生和研究生概括为学生,还可以将学生、教师和职工概括为人。这就是从特殊到一般的过程。

设有实体集 $E$,如果 $S$ 是 $E$ 的某些真子集的集合,记为 $S={S_i \mid S_i \subset E, i=1,2,\cdots,n}$,则称 $S$ 是 $E$ 的一个特殊化,$E$ 是 $S_1, S_2, \cdots, S_n$ 的超类,$S_1, S_2, \cdots, S_n$ 称为 $E$ 的子类。

如果 $\bigcup_{i=1}^{n} S_i = E$,则称 $S$ 是 $E$ 的全特殊化,否则是 $E$ 的部分特殊化。

如果 $S_i \cap S_j = \Phi, i \neq j$,则 $S$ 是不相交特殊化,否则是重叠特殊化。

教职工实体集中的某个职工既是在职生又是教师或工人,那么在职生、教师和工人应该是重叠特殊化;而在职生、教师和工人的集合等于教职工,所以是全部特殊化。

在扩充的 E-R 模型中,子类继承超类的所有属性和联系,但是,子类还有自己特殊的属性和联系。例如,研究生除了学习以外,还要参加科研项目。那么,研究生不仅要继承学生的所有属性,还要增加学位类型、导师的属性,并且需要增加与项目的联系。

在扩充的 E-R 图中,超类-子类关系模型使用特殊化圆圈和连线的一般方式来表示。超类到圆圈有一条连线,连线为双线表示全特殊化,连线为单线表示部分特殊化;双竖边矩形框表示子类;有符号”$\cup$”的线表示特殊化;圆圈中的 d 表示不相交特殊化;圆圈中的 o 表示重叠特殊化;超类与圆圈用单线相连,表示部分特殊化。图9-11给出了一个特殊化应用实例。

9.2.4 数据模型

在数据库领域中常见的数据模型有层次模型、网状模型、关系模型和面向对象模型。本章重点介绍关系模型。

(1)层次模型(Hierarchical Model)采用树型结构表示数据与数据间的联系。在层次模型中,每一个结点表示一个记录类型(实体),记录之间的联系用结点之间的连线表示,并且根结点以外的其他结点有且仅有一个双亲结点。

(2)网状模型(Network Model)也称 DBTG 模型,该是一个比层次模型更具有普遍性的数据结构,是层次模型的一个特例。网状模型可以直接地描述现实世界,因为去掉了层次模型的两个限制,允许两个结点之间有多种联系(称之为复合联系)。

(3)关系模型(Relational Model)是目前最常用的数据模型之一。关系数据库系统采用关系模型作为数据的组织方式,在关系模型中用表格结构表达实体集以及实体集之间的联系,其最大特色是描述的一致性。

(4)面向对象模型(Object Oriented Model)采用面向对象的方法来设计数据库。面向对象的数据库存储对象是以对象为单位,每个对象包含对象的属性和方法,具有类和继承等特点。Computer Associates 的 Jasmine 就是面向对象模型的数据库系统。

面向对象数据模型比网络、层次、关系数据模型具有更加丰富的表达能力。但正因为面向对象模型的丰富表达能力,模型相对复杂,实现起来较困难。

9.2.5 关系模型

关系模型(Relation Model)是目前最常用的数据模型之一。关系数据库系统采用关系模型作为数据的组织方式,在关系模型中用表格结构表达实体集以及实体集之间的联系,其最大特色是描述的一致性。关系模型是由若干个关系模式组成的集合。一个关系模式相当于一个记录型,对应于程序设计语言中类型定义的概念。关系是一个实例,也是一张表,对应于程序设计语言中变量的概念。给定变量的值随时间可能发生变化,类似地,当关系被更新时,关系实例的内容也随时间发生了变化。

【例 9.2】教学数据库的4个关系模式如下:

  • $S(\underline{Sno}, Sname, SD, Sage, Sex)$ ;学生 $S$ 关系模式,属性为学号、姓名、系、年龄和性别
  • $T(\underline{Tno}, Tname, Age, Sex)$ ;教师 $T$ 关系模式,属性为教师号、姓名、年龄和性别
  • $C(\underline{Cno}, Cname, Pcno)$ ;课程 $C$ 关系模式,属性为课程号、课程名和先修课程号
  • $SC(\underline{Sno}, \underline{Cno}, Grade)$ ;学生选课 $SC$ 关系模式,属性为学号、课程号和成绩

关系模式中有下划线的属性是主码属性。图9-12是教学模型的一个具体实例。

由于关系模型比网状、层次模型更加简单、灵活,因此,在数据处理领域中,关系数据库的使用已相当普遍。但是,现实世界中存在着许多含有更复杂数据结构的实际应用领域,例如 CAD 数据、图形数据和人工智能研究等,需要有一种数据模型来表达这类信息,这种数据模型就是面向对象的数据模型。

9.3 关系代数

9.3.1 关系数据库的基本概念

1. 属性和域

在现实世界中,要描述一个事物常常取若干特征来表示,这些特征称为属性(Attribute)。例如,用学号、姓名、性别、系别、年龄和籍贯等属性来描述学生。每个属性的取值范围对应一个值的集合,称为该属性的域(Domain)。例如,学号的域是6位整型数;姓名的域是10位字符;性别的域为{男,女}等。

在关系数据模型中,通常对域加了一个限制,所有的域都应是原子数据(Atomic Data)。例如,整数、字符串是原子数据,而集合、记录、数组是非原子数据。关系数据模型的这种限制称为第一范式(First Normal Form,1NF)条件。但也有些关系数据模型突破了1NF的限制,称为非1NF的关系数据模型。

2. 笛卡儿积与关系

【定义 9.1】设 $D_1, D_2, \cdots, D_i, \cdots, D_n$ 为任意集合,定义 $D_1, D_2, \cdots, D_i, \cdots, D_n$ 的笛卡儿积为

D1×D2×⋯×Di×⋯×Dn=(d1,d2,⋯ ,di,⋯ ,dn)∣di∈Di,i=1,2,3,⋯ ,nD_1 \times D_2 \times \cdots \times D_i \times \cdots \times D_n = {(d_1, d_2, \cdots, d_i, \cdots, d_n) \mid d_i \in D_i, i=1,2,3,\cdots,n}

其中,每一个元素 $(d_1, d_2, \cdots, d_i, \cdots, d_n)$ 称为一个 $n$ 元组(n-tuple 属性的个数),元组的每一个值 $d_i$ 称为元组的一个分量,若 $D_i(i=1,2,3,\cdots,n)$ 为有限集,其基数(Cardinal number 元组的个数)为 $m_i(i=1,2,3,\cdots,n)$,则 $D_1 \times D_2 \times \cdots \times D_i \times \cdots \times D_n$ 的基数 $M$ 为

M=∏i=1nmiM = \prod_{i=1}^{n} m_i

笛卡儿积可以用二维表来表示。

【例 9.3】若 $D_1 = {0,1}$,$D_2 = {a,b}$,$D_3 = {c,d}$,求 $D_1 \times D_2 \times D_3$。

解:根据定义,笛卡儿积中的每一个元素应该是一个三元组,每个分量来自不同的域,因此结果为

D1×D2×D3=(0,a,c),(0,a,d),(0,b,c),(0,b,d),(1,a,c),(1,a,d),(1,b,c),(1,b,d)D_1 \times D_2 \times D_3 = {(0,a,c),(0,a,d),(0,b,c),(0,b,d),(1,a,c),(1,a,d),(1,b,c),(1,b,d)}

用二维表表示如图9-13所示。

【定义 9.2】$D_1 \times D_2 \times \cdots \times D_i \times \cdots \times D_n$ 的子集称为在域 $D_1, D_2, \cdots, D_i, \cdots, D_n$ 上的关系,记为 $R(D_1, D_2, \cdots, D_i, \cdots, D_n)$,称关系 $R$ 为 $n$ 元关系。

从定义9.2可以得出一个关系也可以用二维表来表示。关系中属性的个数称为”元数”,元组的个数称为”基数”。关系模型中的术语与一般术语的对应情况可以通过图9-14中的学生关系说明。图中的学生关系模式可表示为学生 $(S_no, Sname, SD, Sex)$。该学生关系的主码为 $S_no$,属性分别为 $S_no$、$Sname$、$SD$ 和 $Sex$,对属性 $Sex$ 的域为男、女,等等。该学生关系的元数为4,基数为6。

3. 关系的相关名词

(1)目或度(Degree)。这里的 $R$ 表示关系的名字,$n$ 是关系的目或度。

(2)候选码(Candidate Key)。若关系中的某一属性或属性组的值能唯一地标识一个元组,则称该属性或属性组为候选码。

(3)主码(Primary Key)。若一个关系有多个候选码,则选定其中一个为主码。

(4)主属性(Non-Key attribute)。包含在任何候选码中的诸属性称为主属性。不包含在任何候选码中的属性称为非码属性。

(5)外码(Foreign Key)。如果关系模式 $R$ 中的属性或属性组非该关系的码,但它是其他关系的码,那么该属性集对关系模式 $R$ 而言是外码。

例如客户与贷款之间的借贷联系 c-l $(\underline{c\text{-}id}, \underline{loan\text{-}no})$,属性 c-id 是客户关系中的码,所以 c-id 是外码;属性 loan-no 是贷款关系中的码,所以 loan-no 也是外码。

(6)全码(All-Key)。关系模型的所有属性组是这个关系模式的候选码,称为全码。

例如关系模式 $R(T, C, S)$,属性 $T$ 表示教师,属性 $C$ 表示课程,属性 $S$ 表示学生。假设一个教师可以讲授多门课程,某门课程可以由多个教师讲授,学生可以听不同教师讲授的不同课程,那么,要想区分关系中的每一个元组,这个关系模式 $R$ 的码应为全属性 $T$、$C$ 和 $S$,即 All-Key。

4. 关系的3种类型

(1)基本关系。通常又称为基本表或基表,它是实际存在的表,是实际存储数据的逻辑表示。

(2)查询表。查询表是查询结果对应的表。

(3)视图表。视图表是由基本表或其他视图表导出的表。由于它本身不独立存储在数据库中,数据库中只存放它的定义,所以常称为虚表。

5. 关系数据库模式

在数据库中要区分型和值。关系数据库中的型也称为关系数据库模式,是关系数据库结构的描述。它包括若干域的定义以及在这些域上定义的若干关系模式。实际上,关系的概念对应于程序设计语言中变量的概念,而关系模式对应于程序设计语言中类型定义的概念。关系数据库的值是这些关系模式在某一时刻对应的关系的集合,通常称之为关系数据库。

【定义 9.3】关系的描述称为关系模式(Relation Schema),可以形式化地表示为:

R(U,D,dom,F)R(U, D, dom, F)

其中,$R$ 表示关系名;$U$ 是组成该关系的属性名集合;$D$ 是属性的域;$dom$ 是属性向域的映射集合;$F$ 为属性间数据的依赖关系集合。

通常将关系模式简记为:

R(U) 或 R(A1,A2,A3,⋯ ,An)R(U) \text{ 或 } R(A_1, A_2, A_3, \cdots, A_n)

其中,$R$ 为关系名,$A_1, A_2, A_3, \cdots, A_n$ 为属性名或域名,属性向域的映像常常直接说明属性的类型、长度。通常在关系模式主属性上加下划线表示该属性为主码属性。

例如:学生关系 $S$ 有学号 Sno、学生姓名 Same、系名 SD、年龄 SA 属性;课程关系 $C$ 有课程号 Cno、课程名 Cname、选修课程号 Pcno 属性;学生选课关系 $SC$ 有学号 Sno、课程号 Cno、成绩 Grade 属性。定义关系模式及主码如下(本题未考虑 $F$ 属性间数据的依赖,该问题将在后面讨论)。

(1)学生关系模式 $S(\underline{Sno}, Sname, SD, SA)$。

(2)课程关系模式 $C(\underline{Cno}, Cname, Pcno)$,$Dom(Pcno)=Cno$。这里,Pcno 是选修课程号,来自 Cno 域,由于 Pcno 属性名不等于 Cno 值域名,所以要用 Dom 来定义。但是,不能将 Pcno 直接改为 Cno,因为在关系模型中,各列属性必须取相异的名字。

(3)学生选课关系模式 $SC(\underline{Sno}, \underline{Cno}, Grade)$。$SC$ 关系中的 Sno、Cno 又分别为外码,因为它们分别是 $S$、$C$ 关系中的主码。

6. 完整性约束

完整性规则提供了一种手段来保证当授权用户对数据库做修改时不会破坏数据的一致性。因此,完整性规则防止的是对数据的意外破坏。关系模型的完整性规则是对关系的某种约束条件。关系的完整性共分为三类:实体完整性、参照完整性(也称引用完整性)和用户定义完整性。

(1)实体完整性(Entity Integrity)。规定基本关系 $R$ 的主属性 $A$ 不能取空值。

(2)参照完整性(Referential Integrity)。现实世界中的实体之间往往存在某种联系,在关系模型中实体及实体间的联系是用关系来描述的,这样自然就存在着关系与关系间的引用。

例如,员工和部门关系模式的表示如下,其中在关系模式主属性上加下划线表示该属性为主码属性。

员工($\underline{员工号}$,姓名,性别,参加工作时间,部门号)

部门($\underline{部门号}$,名称,电话,负责人)

这两个关系存在着属性的引用,即员工关系中的”部门号”值必须是确实存在的部门的部门号,即部门关系中有该部门的记录。也就是说,员工关系中的”部门号”属性取值要参照部门关系的”部门号”属性取值。

参照完整性规定,若 $F$ 是基本关系 $R$ 的外码,它与基本关系 $S$ 的主码 $K_s$ 相对应(基本关系 $R$ 和 $S$ 不一定是不同的关系),则对于 $R$ 中每个元组在 $F$ 上的值或者取空值($F$ 的每个属性值均为空值),或者等于 $S$ 中某个元组的主码值。

(3)用户定义完整性(User Defined Integrity)。用户定义完整性就是针对某一具体的关系数据库的约束条件,反映某一具体应用所涉及的数据必须满足的语义要求,由应用的环境决定。例如,银行的用户账户规定必须大于等于 100 000、小于 999 999。

7. 关系运算

关系操作的特点是操作对象和操作结果都是集合,而非关系数据模型的数据操作方式则为一次一个记录的方式。关系数据语言分为三类:关系代数语言、关系演算语言和具有关系代数和关系演算双重特点的语言(例如 SQL)。关系演算语言包含元组关系演算语言(例如 Aplha、Quel)和域关系演算语言(例如 QBE)。

关系代数语言、元组关系演算和域关系演算是抽象查询语言,它与具体的 DBMS 中实现的实际语言并不一样,但是可以用它评估实际系统中的查询语言能力的标准。

关系代数运算符有4类:集合运算符、专门的关系运算符、算术比较符和逻辑运算符。根据运算符的不同,关系代数运算可分为传统的集合运算和专门的关系运算。传统的集合运算是从关系的水平方向进行的,包括并、交、差及广义笛卡儿积。专门的关系运算既可以从关系的水平方向进行运算,又可以向关系的垂直方向运算,包括选择、投影、连接以及除法,如表9-2所示。在表9-2中,并、差、笛卡儿积、投影和选择是5种基本的运算,因为其他运算可以通过基本的运算导出。

表9-2 关系代数运算符

类别 运算符 含义 类别 运算符 含义
集合运算符 $\cup$ 并 比较运算符 $>$ 大于
$-$ 差 $\geq$ 大于等于
$\cap$ 交 $<$ 小于
$\times$ 笛卡儿积 $\leq$ 小于等于
专门的关系运算符 $\sigma$ 选择 $=$ 等于
$\pi$ 投影 $\neq$ 不等于
$\bowtie$ 连接 逻辑运算符 $\neg$ 非
$\div$ 除 $\wedge$ 与
$\vee$ 或

9.3.2 5种基本的关系代数运算

5种基本的关系代数运算包括并、差、笛卡儿积、投影和选择,其他运算可以通过基本的关系运算导出。

1. 并(Union)

关系 $R$ 与 $S$ 具有相同的关系模式,即 $R$ 与 $S$ 的元数相同(结构相同)。关系 $R$ 与 $S$ 的并是由属于 $R$ 或属于 $S$ 的元组构成的集合,记作 $R \cup S$,其形式定义如下:

R∪S=t∣t∈R∨t∈SR \cup S = {t \mid t \in R \lor t \in S}

式中 $t$ 为元组变量。

2. 差(Difference)

关系 $R$ 与 $S$ 具有相同的关系模式,关系 $R$ 与 $S$ 的差是由属于 $R$ 但不属于 $S$ 的元组构成的集合,记作 $R - S$,其形式定义如下:

R−S=t∣t∈R∧t∉SR - S = {t \mid t \in R \land t \notin S}

3. 广义笛卡儿积(Extended Cartesian Product)

两个元数分别为 $n$ 目和 $m$ 目的关系 $R$ 和 $S$ 的广义笛卡儿积是一个 $(n+m)$ 列的元组的集合。元组的前 $n$ 列是关系 $R$ 的一个元组,后 $m$ 列是关系 $S$ 的一个元组,记作 $R \times S$,其形式定义如下:

R×S=t∣t=⟨tn,tm⟩∧tn∈R∧tm∈SR \times S = {t \mid t = \langle t^n, t^m \rangle \land t^n \in R \land t^m \in S}

如果 $R$ 和 $S$ 中有相同的属性名,可在属性名前加关系名作为限定,以示区别。若 $R$ 有 $K_1$ 个元组,$S$ 有 $K_2$ 个元组,则 $R$ 和 $S$ 的广义笛卡儿积有 $K_1 \times K_2$ 个元组。

注意:本教材中的 $\langle t^n, t^m \rangle$ 意为元组 $t^n$ 和 $t^m$ 拼接成的一个元组。

4. 投影(Projection)

投影运算是从关系的垂直方向进行运算,在关系 $R$ 中选出若干属性列 $A$ 组成新的关系,记作 $\pi_A(R)$,其形式定义如下:

πA(R)=t[A]∣t∈R\pi_A(R) = {t[A] \mid t \in R}

5. 选择(Selection)

选择运算是从关系的水平方向进行运算,是从关系 $R$ 中选择满足给定条件的诸元组,记作 $\sigma_F(R)$,其形式定义如下:

σF(R)=t∣t∈R∧F(t)=True\sigma_F(R) = {t \mid t \in R \land F(t) = \text{True}}

其中,$F$ 中的运算对象是属性名(或列的序号)或常数,运算符、算术比较符($<$、$\leq$、$>$、$\geq$、$\neq$)和逻辑运算符($\land$、$\lor$、$\neg$)。例如,$\sigma{1 \geq 6}(R)$ 表示选取 $R$ 关系中第1个属性值大于等于第6个属性值的元组;$\sigma{1 \geq 6}(R)$ 表示选取 $R$ 关系中第1个属性值大于等于6的元组。

【例 9.4】设有关系 $R$、$S$ 如下所示,请求出 $R \cup S$、$R - S$、$R \times S$、$\pi{A,C}(R)$、$\sigma{A>B}(R)$ 和 $\sigma_{3<4}(R \times S)$。

解:$R \cup S$、$R - S$、$R \times S$、$\pi{A,C}(R)$、$\sigma{A>B}(R)$ 和 $\sigma_{3<4}(R \times S)$ 的结果如图9-15所示。

其中,$R \times S$ 生成的关系属性名有重复,按照关系”属性不能重名”的性质,通常采用”关系名.属性名”的格式。对于 $\sigma{3<4}(R \times S)$ 的含义是 $R \times S$ 后”选取第3个属性值小于第4个属性值”的元组。由于 $R \times S$ 的第3个属性为 R.C,第4个属性是 S.A,因此 $\sigma{3<4}(R \times S)$ 的含义也是 $R \times S$ 后”选取 R.C 值小于 S.A 值”的元组。

9.3.3 扩展的关系代数运算

扩展的关系代数运算可以从基本的关系运算中导出,主要包括选择、投影、连接、除法、广义笛卡儿积和外连接。

1. 交(Intersection)

关系 $R$ 与 $S$ 具有相同的关系模式,关系 $R$ 与 $S$ 的交是由属于 $R$ 同时又属于 $S$ 的元组构成的集合,记作 $R \cap S$,其形式定义如下:

R∩S=t∣t∈R∧t∈SR \cap S = {t \mid t \in R \land t \in S}

显然,$R \cap S = R - (R - S)$,或者 $R \cap S = S - (S - R)$。

2. 连接(Join)

连接分为 $\theta$ 连接、等值连接和自然连接3种。连接运算是从两个关系 $R$ 和 $S$ 的笛卡儿积中选取满足条件的元组。因此,可以认为笛卡儿积是无条件连接,其他的连接操作认为是有条件连接,下面分别介绍。

(1)$\theta$ 连接。从 $R$ 与 $S$ 的笛卡儿积中选取属性间满足一定条件的元组。记作:

R⋈XθYS=t∣t=⟨tn,tm⟩∧tn∈R∧tm∈S∧tn[X]θtm[Y]R \underset{X\theta Y}{\bowtie} S = {t \mid t = \langle t^n, t^m \rangle \land t^n \in R \land t^m \in S \land t^n[X] \theta t^m[Y]}

其中,$X\theta Y$ 为连接的条件,$\theta$ 是比较运算符,$X$ 和 $Y$ 分别为 $R$ 和 $S$ 上度数相等且可比的属性组。$t^n[X]$ 表示 $R$ 中 $t^n$ 元组的对应于属性 $X$ 的一个分量。$t^m[Y]$ 表示 $S$ 中 $t^m$ 元组的对应于属性 $Y$ 的一个分量。有如下说明。

① $\theta$ 连接也可以表示为:

R⋈iθjS=t∣t=⟨tn,tm⟩∧tn∈R∧tm∈S∧tn[i]θtm[j]R \underset{i\theta j}{\bowtie} S = {t \mid t = \langle t^n, t^m \rangle \land t^n \in R \land t^m \in S \land t^n[i] \theta t^m[j]}

其中,$i=1,2,3,\cdots,n$,$j=1,2,3,\cdots,m$,$i\theta j$ 的含义为从两个关系 $R$ 和 $S$ 中选取 $R$ 的第 $i$ 列和 $S$ 的第 $j$ 列之间满足 $\theta$ 运算的元组进行连接。

② $\theta$ 连接可以由基本的关系运算笛卡儿积和选取运算导出。因此,$\theta$ 连接可表示为:

R⋈XθYS=σXθY(R×S) 或 R⋈iθjS=σiθ(i+j)(R×S)R \underset{X\theta Y}{\bowtie} S = \sigma{X\theta Y}(R \times S) \text{ 或 } R \underset{i\theta j}{\bowtie} S = \sigma{i\theta (i+j)}(R \times S)

【例 9.5】设有关系 $R$、$S$ 如图9-16所示,求 $R \underset{R.A<S.B}{\bowtie} S$。

解:本题连接的条件为 $R.A < S.B$,意为将 $R$ 关系中属性 $A$ 的值小于 $S$ 关系中属性 $B$ 的值的元组取出来作为结果集的元组。结果集为 $R \times S$ 后选出满足条件的元组,并且结果集的属性为 $R.A$、$R.B$、$R.C$、$S.A$、$S.B$、$S.C$。结果如图9-16所示。

(2)等值连接。当 $\theta$ 为 “$=$” 时,称之为等值连接,记为 $R \underset{X=Y}{\bowtie} S$,其形式定义如下:

R⋈X=YS=t∣t=⟨tn,tm⟩∧tn∈R∧tm∈S∧tn[X]=tm[Y]R \underset{X=Y}{\bowtie} S = {t \mid t = \langle t^n, t^m \rangle \land t^n \in R \land t^m \in S \land t^n[X] = t^m[Y]}

(3)自然连接。自然连接是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且在结果集中将重复属性列去掉。若 $t^n$ 表示 $R$ 关系的元组变量,$t^m$ 表示 $S$ 关系的元组变量;$R$ 和 $S$ 具有相同的属性组 $B$,且 $B=(B1, B_2, \cdots, B_K)$;并假定 $R$ 关系的属性为 $A_1, A_2, \cdots, A{n-k}, B1, B_2, \cdots, B_K$,$S$ 关系的属性为 $B_1, B_2, \cdots, B_K, B{K+1}, B_{K+2}, \cdots, B_m$;为 $S$ 的元组变量 $t^m$ 去掉重复属性 $B$ 所组成的新的元组变量为 $t^{m^*}$。

自然连接可以记为 $R \bowtie S$,其形式定义如下:

R⋈S=t∣t=⟨tn,tm∗⟩∧tn∈R∧tm∈S∧R.B1=S.B1∧R.B2=S.B2∧⋯∧R.Bk=S.BkR \bowtie S = {t \mid t = \langle t^n, t^{m^*} \rangle \land t^n \in R \land t^m \in S \land R.B_1=S.B_1 \land R.B_2=S.B_2 \land \cdots \land R.B_k=S.B_k}

自然连接可以由基本的关系运算笛卡儿积和选取运算导出,因此自然连接可表示为:

R⋈S=∏A1,A2,⋯ ,An−k,R.B1,R.B2,⋯ ,R.BK,BK+1,BK+2,⋯ ,Bm(σR.B1=S.B1∧R.B2=S.B2∧⋯∧R.BK=S.BK(R×S))R \bowtie S = \prod{A_1, A_2, \cdots, A{n-k}, R.B1, R.B_2, \cdots, R.B_K, B{K+1}, B{K+2}, \cdots, B_m}(\sigma{R.B_1=S.B_1 \land R.B_2=S.B_2 \land \cdots \land R.B_K=S.B_K}(R \times S))

需要特别说明的是,一般连接是从关系的水平方向运算,而自然连接不仅要从关系的水平方向运算,而且要从关系的垂直方向运算。因为自然连接要去掉重复属性,如果没有重复属性,那么自然连接就转化为笛卡儿积。

【例 9.6】设有关系 $R$、$S$ 如图9-17所示,求 $R \bowtie S$。

解:本题要求 $R$ 与 $S$ 关系的自然连接,自然连接是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且在结果中将重复属性列去掉。本题 $R$ 与 $S$ 关系中相同的属性组为 AC,因此,结果集中的属性列应为 ABCD,其结果如图9-18所示。

3. 除(Division)

除运算是同时从关系的水平方向和垂直方向进行运算。给定关系 $R(X,Y)$ 和 $S(Y,Z)$,$X$、$Y$、$Z$ 为属性组。$R \div S$ 应当满足元组在 $X$ 上的分量值 $x$ 的象集 $Y_x$ 包含关系 $S$ 在属性组 $Y$ 上投影的集合。其形式定义如下:

R÷S=tn[X]∣tn∈R∧πY(S)⊆YxR \div S = {t^n[X] \mid t^n \in R \land \pi_Y(S) \subseteq Y_x}

其中,$Y_x$ 为 $x$ 在 $R$ 中的象集,$x = t^n[X]$,且 $R \div S$ 的结果集的属性组为 $X$。

【例 9.7】设有关系 $R$、$S$ 如图9-19所示,求 $R \div S$。

解:根据除法定义,此题的 $X$ 为属性 $AB$,$Y$ 为属性 $CD$。$R \div S$ 应当满足元组在属性 $AB$ 上的分量值 $x$ 的象集 $Y_x$ 包含关系 $S$ 在 $CD$ 上投影的集合。

关系 $S$ 在 $Y$ 上的投影为 $\pi_{CD}(S) = {(c,d),(e,f)}$。对于关系 $R$,属性组 $X$(即 $AB$)可以取3个值,即 ${(a,b),(b,d),(c,k)}$,它们的象集分别为:

  • 象集 $CD_{(a,b)} = {(c,d),(e,f),(h,k)}$
  • 象集 $CD_{(b,d)} = {(e,f),(d,l)}$
  • 象集 $CD_{(c,k)} = {(c,d),(e,f)}$

由于上述象集包含 $\pi_{CD}(S)$ 有 $(a,b)$ 和 $(c,k)$,因此 $R \div S = {(a,b),(c,k)}$,结果如图9-19(c)所示。

【例 9.8】设学生课程数据库中有学生 $S$、课程 $C$ 和学生选课 $SC$ 这3个关系,如图9-20所示,请用关系代数表达式表达以下检索问题。

(1)检索选修课程名为”数学”的学生的学号和姓名。

(2)检索至少选修了课程号为1和3的学生的学号。

(3)检索选修了”操作系统”或”数据库”课程的学生的学号和姓名。

(4)检索年龄在 18~20 之间(含18和20)的女生的学号、姓名及年龄。

(5)检索选修了”数据库”课程的学生的学号、姓名及成绩。

(6)检索选修了全部课程的学生的姓名所在系。

(7)检索选修课程包括1042学生所学课程的学生的学号。

(8)检索不选修2课程的学生的姓名和所在系。

解:(1)检索选修课程名为”数学”的学生的学号和姓名的关系代数表达式如下。

πSno,Sname(σCname=’数学’(S⋈SC⋈C)) 或 π1,2(σ8=’数学’(S⋈SC⋈C))\pi{Sno,Sname}(\sigma{Cname=’数学’}(S \bowtie SC \bowtie C)) \text{ 或 } \pi{1,2}(\sigma{8=’数学’}(S \bowtie SC \bowtie C))

对于上述表达式 $S \bowtie SC \bowtie C$ 自然连接后重复的属性列为学号 Sno 和课程号 Cno,去掉重复属性列的结果如图9-21所示。从图中可以看到,满足课程名为”数学”的只有3个元组,对 Sno 和 Sname 投影的结果如图9-22所示。由于 Sno、Cno 和 Cname 分别对应第1、2和8列属性,所以上述表达式还可以写为 $\pi{1,2}(\sigma{8=’数学’}(S \bowtie SC \bowtie C))$。

(2)检索至少选修了课程号为1和3的学生的学号有以下两种解题思路。

① 关系代数表达式为 $\pi1(\sigma{1=4 \land 2=’1’ \land 5=’3’}(SC \times SC))$。若设 $SC \times SC$ 中的第一个 $SC$ 关系为 S1,第二个 $SC$ 关系为 S2,那么,该关系表达式的含义为先从 $SC \times SC$ 中选取满足条件 S1.Sno=S2.Sno、S1.Cno=’1’、S2.Sno=’3’ 的元组,最后投影第一个属性列 Sno 即为所求结果集。

② 关系代数表达式为 $\pi{Sno,Cno}(SC) \div \pi{Cno}(\sigma_{Cno=’1’ \lor Cno=’3’}(C))$,分析如下。

表达式 $\pi{Cno}(\sigma{Cno=’1’ \lor Cno=’3’}(C))$ 就是构造一个临时关系 $K$,其属性为 Cno,结果如下:

K=πCno(σCno=’1’∨Cno=’3’(C))=1,3K = \pi{Cno}(\sigma{Cno=’1’ \lor Cno=’3’}(C)) = {1,3}

查询表达式 $\pi_{Sno,Cno}(SC) \div K$ 的结果集的学生号所选的课程号应包括 $K$。

求解的过程就是对 $\pi{Sno,Cno}(SC)$ 的每一个元组逐一求某一学生的象集。因为所求的 Sno,所以 $X$ 为 Sno,$Y$ 为 Cno,所以象集为 $Cno{Sno}$。将 Sno 的值逐一代入求象集:

Cno3001=1,2,3,Cno3002=2,3,Cno1042=1,2Cno{3001} = {1,2,3}, \quad Cno{3002} = {2,3}, \quad Cno_{1042} = {1,2}

从上可以看出,只有3001包含了 $K$ 在 Cno 的投影,所以,$\pi_{Sno,Cno}(SC) \div K = {3001}$。

(3)检索选修了”操作系统”或”数据库”课程的学生的学号和姓名的关系代数表达式为:

πSno,Sname(S⋈(σCname=’操作系统’∨Cname=’数据库’(SC⋈C)))\pi{Sno,Sname}(S \bowtie (\sigma{Cname=’操作系统’ \lor Cname=’数据库’}(SC \bowtie C)))

(4)检索年龄在 18~20 之间(含18和20)的女生的学号、姓名及年龄的关系代数表达式为:

πSno,Sname,Age(σAge≥‘18’∧Age≤‘20’∧Sex=’女’(S))\pi{Sno,Sname,Age}(\sigma{Age \geq ‘18’ \land Age \leq ‘20’ \land Sex=’女’}(S))

(5)检索选修了”数据库”课程的学生的学号、姓名及成绩的关系代数表达式为:

πSno,Sname,Grade((σCname=’数据库’(S⋈SC⋈C)))\pi{Sno,Sname,Grade}((\sigma{Cname=’数据库’}(S \bowtie SC \bowtie C)))

(6)检索选修了全部课程的学生的姓名及所在系的关系代数表达式为:

πSname,SD(S⋈(πSno,Cno(SC)÷πCno(C)))\pi{Sname,SD}(S \bowtie (\pi{Sno,Cno}(SC) \div \pi_{Cno}(C)))

对于本题给出的具体关系,求解过程分析如下。

① 表示全部课程的临时关系 $K = \pi_{Cno}(C) = {1,2,3,4,5,6,7}$。

② 查询选修了所有课程的学生的学号为 $\pi{Sno,Cno}(SC) \div K = {\emptyset}$,因为学生所选课程分别为 $Cno{3001}={1,2,3}$、$Cno{3002}={2,3}$ 和 $Cno{1042}={1,2}$,所以3001、3002和1042都没有包含 $K$,故结果集为空。

③ 与 $S$ 关系进行自然连接再对学生姓名 Sname 和学号 SD 投影的结果也为空。

(7)检索选修课程包括1042学生所学课程的学生的学号的关系表达式如下:

πSno,Cno(SC)÷πCno(σSno=’1042’(SC))\pi{Sno,Cno}(SC) \div \pi{Cno}(\sigma_{Sno=’1042’}(SC))

(8)检索不选修2课程的学生的姓名和所在系的关系代数表达式为:

πSname,SD(SC)−πSname,SD(σCno=’2’(S×SC))\pi{Sname,SD}(SC) - \pi{Sname,SD}(\sigma_{Cno=’2’}(S \times SC))

对于上式也可以用属性列号替换属性名,将上式写成以下等价的关系代数表达式:

π2,4(SC)−π2,4(σ6=’2’(S⋈SC))\pi{2,4}(SC) - \pi{2,4}(\sigma_{6=’2’}(S \bowtie SC))

4. 广义投影(Generalized Projection)

广义投影运算允许在投影列表中使用算术运算,实现了对投影运算的扩充。

若有关系 $R$,条件 $F1, F_2, \cdots, F_n$ 中的每一个都是涉及 $R$ 中常量和属性的算术表达式,那么广义投影运算的形式定义为:$\pi{F_1, F_2, \cdots, F_n}(R)$。

【例 9.9】信贷额度关系模式 credit-in(Cname, limit, credit_balance),属性分别表示用户姓名、信贷额度和到目前为止的花费。图9-23(a)表示了关系 credit-in 的一个具体。若要查询给出每个用户还能花费多少,可以用关系代数表达式 $\pi{C_name, limit-credit_balance}(\text{credit-in})$ 来表示,查询结果如图9-23(b)所示。

5. 外连接(Outer Join)

外连接运算是连接运算的扩展,可以处理由于连接运算而缺失的信息。对于图9-20所示的 $S$ 和 $SC$ 关系,当对其进行自然连接 $S \bowtie SC$ 时,其结果如图9-24所示。

从图9-24可以看出,$S$ 与 $SC$ 的自然连接 $S \bowtie SC$ 的结果丢失了黎明、刘明远、赵国庆的相关信息。但是,使用外连接可以避免这样的信息丢失。外连接运算有3种,即左外连接、右外连接和全外连接。

(1)左外连接(Left Outer Join)$\bowtie!!-$。取出左侧关系中所有与右侧关系中任一元组都不匹配的元组,用空值 null 充填所有来自右侧关系的属性,构成新的元组,将其加入自然连接的结果中。对于图9-20所示的 $S$ 和 $SC$ 关系,当对其进行左外连接 $S \bowtie!!- SC$ 时,其结果如图9-25所示。

(2)右外连接(Right Outer Join)$-!!\bowtie$。取出右侧关系中所有与左侧关系中任一元组都不匹配的元组,用空值 null 填充所有来自左侧关系的属性,构成新的元组,将其加入自然连接的结果中。对于图9-20所示关系 $SC$ 和 $C$,当进行右外连接 $SC -!!\bowtie C$ 时,其结果如图9-26所示。

(3)全外连接(Full Outer Join)$\bowtie$。完成左外连接和右外连接的操作。即填充左侧关系中所有与右侧关系中任一元组都不匹配的元组,并填充右侧关系中所有与左侧关系中任一元组都不匹配的元组,将产生的新元组加入自然连接的结果中。

【例 9.10】设有关系 $R$、$S$ 如图9-27所示,求 $R \bowtie!!- S$、$R -!!\bowtie S$ 和 $R \bowtie S$。

对于图9-27所示的 $R$、$S$ 关系,当对其进行左外连接 $R \bowtie!!- S$,右外连接 $R -!!\bowtie S$,全外连接 $R \bowtie S$ 时,其结果分别如图9-28(a)、图9-28(b)和图9-28(c)所示。

9.4 关系数据库 SQL 语言简介

SQL(Structured Query Language)早已确立起自己作为关系数据库标准语言的地位,已被众多商用 DBMS 产品(如 DB2、ORACLE、INGRES、SYSBASE、SQL Server 和 VFP 等)所采用,使得它已成为关系数据库领域中的一个主流语言。SQL 是在1974年由 Boyce 和 Chamberlin 提出的,它是关系数据库中最普遍使用的语言,包括数据查询(Query)、数据操纵(Manipulation)、数据定义(Definition)和数据控制(Control)功能,是一种通用的、功能强大的关系数据库的标准语言。

9.4.1 SQL 数据库体系结构

SQL 主要有3个标准:ANSI(美国国家标准机构)SQL;对 ANSI SQL 进行修改后在1992年采用的标准 SQL-92 或 SQL2;最近的 SQL-99 标准,也称为 SQL3 标准。SQL-99 从 SQL-92 扩充而来,并增加了对象关系特征和许多其他新的功能。

1. SQL 的特点

SQL 的特点如下。

(1)综合统一。非关系模型的数据语言分为模式定义语言和数据操纵语言,其缺点是当要修改模式时,必须停止现有数据库的运行,转储数据,修改模式编译后再重装数据库。SQL 集数据定义、数据操纵和数据控制功能于一体,语言风格统一,可独立完成数据库生命周期的所有活动。

(2)高度非过程化。非关系数据模型的数据操纵语言是面向过程的,若要完成某项请求,必须指定存储路径;而 SQL 语言是高度非过程化语言,当进行数据操作时,只要指出”做什么”,无须指出”怎么做”,存储路径对用户来说是透明的,提高了数据的独立性。

(3)面向集合的操作方式。非关系数据模型采用的是面向记录的操作方式,操作对象是一条记录。而 SQL 语言采用面向集合的操作方式,其操作对象、查找结果可以是元组的集合。

(4)两种使用方式。第一种方式,用户可以在终端键盘上输入 SQL 命令,对数据库进行操作,故称之为自含式语言;第二种方式,将 SQL 语言嵌入到高级语言程序中,所以又称为嵌入式语言。

(5)语言简洁、易学易用。SQL 语言功能极强,完成核心功能只用了9个动词,包括以下4类。

  • 数据查询:SELECT。
  • 数据定义:CREATE、DROP、ALTER。
  • 数据操纵:INSERT、UPDATE、DELETE。
  • 数据控制:GRANT、REVOKE。

2. SQL 支持三级模式结构

SQL 语言支持关系数据库的三级模式结构,其中,视图对应外模式、基本表对应模式、存储文件对应内模式。具体结构如图9-29所示。

9.4.2 SQL 的基本组成

SQL 由以下几个部分组成。

(1)数据定义语言。SQL DDL 提供定义关系模式和视图、删除关系和视图、修改关系模式的命令。

(2)交互式数据操纵语言。SQL DML 提供查询、插入、删除和修改的命令。

(3)事务控制(Transaction Control)。SQL 提供定义事务开始和结束的命令。

(4)嵌入式 SQL 和动态 SQL(Embeded SQL and Dynamic SQL)。用于嵌入到某种通用的高级语言(C、C++、Java、PL/I、COBOL 和 VB 等)中混合编程。其中,SQL 负责操纵数据库,高级语言负责控制程序流程。

(5)完整性(Integrity)。SQL DDL 包括定义数据库中的数据必须满足的完整性约束条件的命令,对于破坏完整性约束条件的更新将被禁止。

(6)权限管理(Authorization)。SQL DDL 中包括说明对关系和视图的访问权限。

9.4.3 SQL 数据定义

基本表和视图都是表,所不同的是基本表是实际存储在数据库中的表,视图是虚表,是从基本表或其他视图中导出的表。数据库中只存放视图的定义,不存放视图的数据。用户可用 SQL 语句对基本表和视图进行查询等操作,在用户看来,基本表和视图一样,都是关系(即表)。一个基本表可以存储在一个或多个存储文件中,一个存储文件也可以存储一个或多个基本表。一个表可以带若干索引,索引也存储在存储文件中。每个存储文件就是外部存储器上的一个物理文件,存储文件的逻辑结构组成了关系数据库的内模式。

SQL 的数据定义包括对表、视图、索引的创建和删除。

1. 创建表(CREATE TABLE)

语句格式:CREATE TABLE <表名>(<列名><数据类型>[列级完整性约束条件]

[,<列名><数据类型>[列级完整性约束条件]]…

[,<表级完整性约束条件>]);

列级完整性约束条件有 NULL(空)和 UNIQUE(取值唯一),如 NOT NULL UNIQUE 表示取值唯一,不能取空值。

【例 9.11】建立一个供应商、零件数据库。其中,”供应商”表 S(Sno,Sname,Status,City)分别表示供应商代码、供应商名、供应商状态和供应商所在城市。”零件”表 P(Pno,Pname,Color,Weight,City)表示零件号、零件名、颜色、重量及产地。数据库要满足以下要求。

(1)供应商代码不能为空,且值是唯一的,供应商的名也是唯一的。

(2)零件号不能为空,且值是唯一的;零件名不能为空。

(3)一个供应商可以供应多个零件,而一个零件可以由多个供应商供应。

分析:根据题意,供应商和零件分别要建立一个关系模式。供应商和零件之间是一个多对多的联系,在关系数据库中,多对多联系必须生成一个关系模式,而该模式的码是该联系两端实体的码加上联系的属性构成的,若该联系名为 SP,那么关系模式为 SP(Sno, Pno, Qty),其中,Qty 表示零件的数量。

根据上述分析,用 SQL 建立一个供应商、零件数据库如下:

  1. CREATE TABLE S(
  2. Sno CHAR(5) NOT NULL UNIQUE,
  3. Sname CHAR(30) UNIQUE,
  4. Status CHAR(8),
  5. City CHAR(20),
  6. PRIMARY KEY(Sno)
  7. );
  8. CREATE TABLE P(
  9. Pno CHAR(6),
  10. Pname CHAR(30) NOT NULL,
  11. Color CHAR(8),
  12. Weight NUMERIC(6,2),
  13. City CHAR(20),
  14. PRIMARY KEY(Pno)
  15. );
  16. CREATE TABLE SP(
  17. Sno CHAR(5),
  18. Pno CHAR(6),
  19. Qty NUMERIC(9),
  20. PRIMARY KEY(Sno, Pno),
  21. FOREIGN KEY(Sno) REFERENCES S(Sno),
  22. FOREIGN KEY(Pno) REFERENCES P(Pno)
  23. );

从上述定义可以看出,Sno CHAR(5) NOT NULL UNIQUE 语句定义了 Sno 的列级完整性约束条件,取值唯一,不能取空值。

需要说明如下。

(1)PRIMARY KEY(Sno) 已经定义了 Sno 为主码,所以 Sno CHAR(5) NOT NULL UNIQUE 语句中的 NOT NULL UNIQUE 可以省略。

(2)FOREIGN KEY(Sno) REFERENCES S(Sno) 定义了在 SP 关系中 Sno 为外码,其取值必须来自 S 关系的 Sno 域。同理,在 SP 关系中 Pno 也定义为外码。

2. 修改和删除表

1)修改表(ALTER TABLE)

语句格式:ALTER TABLE <表名>[ADD <新列名> <数据类型> [完整性约束条件]]

[DROP <完整性约束名>]

[MODIFY <列名> <数据类型>];

例如,向”供应商”表 S 增加 Zap”邮政编码”可用如下语句:

  1. ALTER TABLE S ADD Zap CHAR(6);

注意:不论基本表中原来是否已有数据,新增加的列一律为空。

又如,将 Status 字段改为整型可用如下语句:

  1. ALTER TABLE S MODIFY Status INT;
2)删除表(DROP TABLE)

语句格式:DROP TABLE <表名>

例如执行 DROP TABLE Student,此后关系 Student 不再是数据库模式的一部分,关系中的元组也无法访问。

3. 索引建立与删除

数据库中的索引与书籍中的索引类似,在一本书中,利用索引可以快速地查找所需信息,而无须阅读整本书。在数据库中,索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需数据。书中的索引是一个词语列表,其中注明了包含各个词的页码。而数据库中的索引是某个表中一列或者若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用如下。

(1)通过创建唯一索引,可以保证数据记录的唯一性。

(2)可以大大加快数据的检索速度。

(3)可以加速表与表之间的连接,这一点在实现数据的参照完整性方面有特别的意义。

(4)在使用 ORDER BY 和 GROUP BY 子句中进行检索数据时,可以显著减少查询中分组和排序的时间。

(5)使用索引可以在检索数据的过程中使用优化隐藏器,提高系统性能。

索引分为聚集索引和非聚集索引。聚集索引是指索引表中索引项的顺序与表中记录的物理顺序一致的索引。

1)建立索引

语句格式:CREATE [UNIQUE][CLUSTER] INDEX <索引名>

ON <表名>(<列名>[<次序>][,<列名>[<次序>]]…);

参数说明如下。

  • 次序:可选 ASC(升序)或 DSC(降序),默认值为 ASC。
  • UNIQUE:表明此索引的每一个索引值只对应唯一的数据记录。
  • CLUSTER:表明要建立的索引是聚簇索引,意为索引项的顺序是与表中记录的物理顺序一致的索引组织。

【例 9.12】假设供应销售数据库中有供应商 S、零件 P、工程项目 J、供销情况 SPJ 关系,希望建立4个索引。其中,供应商 S 中 Sno 按升序建立索引;零件 P 中 Pno 按升序建立索引;工程项目 J 中 Jno 按升序建立索引;供销情况 SPJ 中 Sno 按升序、Pno 按降序、Jno 按升序建立索引。

解:根据题意建立的索引如下。

  1. CREATE UNIQUE INDEX S-SNO ON S(Sno);
  2. CREATE UNIQUE INDEX P-PNO ON P(Pno);
  3. CREATE UNIQUE INDEX J-JNO ON J(Jno);
  4. CREATE UNIQUE INDEX SPJ-NO ON SPJ(Sno ASC, Pno DESC, JNO ASC);
2)删除索引

语句格式:DROP INDEX <索引名>

例如执行 DROP INDEX StudentIndex,此后索引 StudentIndex 不再是数据库模式的一部分。

4. 视图创建与删除

视图是从一个或者多个基本表或视图中导出的表,其结构和数据是建立在对表的查询基础上的。和真实的表一样,视图也包括几个被定义的数据列和多个数据行,但从本质上讲,这些数据列和数据行来源于其所引用的表。因此,视图不是真实存在的基本表,而是一个虚拟表,视图所对应的数据并不实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。使用视图的优点和作用如下。

(1)可以使用视图集中数据、简化和定制不同用户对数据库的不同数据要求。

(2)使用视图可以屏蔽数据的复杂性,用户不必了解数据库的结构,就可以方便地使用和管理数据,简化数据权限管理和重新组织数据以便输出到其他应用程序中。

(3)视图可以使用户只关心他感兴趣的某些特定数据和他们所负责的特定任务,而那些不需要的或者无用的数据则不在视图中显示。

(4)视图大大地简化了用户对数据的操作。

(5)视图可以让不同的用户以不同的方式看到不同或者相同的数据集。

(6)在某些情况下,由于表中数据量太大,因此在设计表时常将表进行水平或者垂直分割,以免表的结构的变化对应用程序产生不良的影响。

(7)视图提供了一个简单而有效的安全机制。

1)视图的创建

语句格式:CREATE VIEW 视图名(列表名)

AS SELECT 查询子句

[WITH CHECK OPTION];

注意:在视图的创建中必须遵循以下规定。

(1)子查询可以是任意复杂的 SELECT 语句,但通常不允许含有 ORDER BY 子句和 DISTINCT 短语。

(2)WITH CHECK OPTION 表示对 UPDATE、INSERT、DELETE 操作时保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)。

(3)组成视图的属性列名或者全部省略或者全部指定。如果省略属性列名,则隐含该视图由 SELECT 子查询目标列的主属性组成。

【例 9.13】若学生关系模式为 Student(Sno, Sname, Sage, Sex, SD, Email, Tel),建立”计算机系”(CS 表示计算机系)学生的视图,并要求进行修改、插入操作时保证该视图中只有计算机系的学生。

  1. CREATE VIEW CS-STUDENT
  2. AS SELECT Sno, Sname, Sage, Sex
  3. FROM Student
  4. WHERE SD='CS'
  5. WITH CHECK OPTION;

由于 CS-STUDENT 视图使用了 WITH CHECK OPTION 子句,因此,对该视图进行修改、插入操作时 DBMS 会自动加上 SD=’CS’的条件,保证该视图中只有计算机系的学生。

2)视图的删除

语句格式:DROP VIEW 视图名

例如,DROP VIEW CS-STUDENT 将删除视图 CS-STUDENT。

9.4.4 SQL 数据查询

SQL 的数据操纵功能包括 SELECT(查询)、INSERT(插入)、DELETE(删除)和 UPDATE(修改)这4条语句。SQL 语言对数据库的操作十分灵活、方便,原因在于 SELECT 语句中成分丰富多样的元组,有许多可选形式,尤其是目标列和条件表达式。

本小节数据查询以图9-20所示的学生选课数据库为例。

1. SELECT 基本结构

数据库查询是数据库的核心操作,SQL 语言提供了 SELECT 语句进行数据库的查询。

语句格式:SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>]…

FROM <表名或视图名>[,<表名或视图名>]

[WHERE <条件表达式>]

[GROUP BY <列名1> [HAVING <条件表达式>]]

[ORDER BY <列名2> [ASC|DESC]…];

SQL 查询中的子句顺序为 SELECT、FROM、WHERE、GROUP BY、HAVING 和 ORDER BY。其中,SELECT、FROM 是必需的,HAVING 条件子句只能与 GROUP BY 搭配起来使用。

(1)SELECT 子句对应的是关系代数中的投影运算,用来列出查询结果中的属性。其输出可以是列名、表达式、集函数(AVG、COUNT、MAX、MIN、SUM),DISTINCT 选项可以保证查询的结果集中不存在重复元组。

(2)FROM 子句对应的是关系代数中的笛卡儿积,它列出的是表达式求值过程中需扫描的关系,即在 FROM 子句中出现多个基本表或视图时,系统首先执行笛卡儿积操作。

(3)WHERE 子句对应的是关系代数中的选择谓词。WHERE 子句的条件表达式中可以使用的运算符如表9-3所示。

表9-3 WHERE 子句的条件表达式中可以使用的运算符

运算符 含义 运算符 含义
IN 在集合中 $>$ 大于
NOT IN 不在集合中 $\geq$ 大于等于
LIKE 与_和%进行单个、多个字符匹配 $<$ 小于
IS NULL 为空 $\leq$ 小于等于
IS NOT NULL 不能为空 $=$ 等于
AND 与 $\neq$ 不等于
OR 或
NOT 非

一个典型的 SQL 查询具有以下形式:

  1. SELECT A_1, A_2, ..., A_n
  2. FROM r_1, r_2, ... r_m
  3. WHERE p;

对应关系代数表达式为 $\prod_{A_1, A_2, \cdots, A_n}(\sigma_p(r_1 \times r_2 \times \cdots \times r_m))$。

2. 简单查询

SQL 最简单的查询是找出关系中满足特定条件的元组,这些查询与关系代数中的选择操作类似。简单查询只需要使用3个保留字,即 SELECT、FROM 和 WHERE。

【例 9.14】查询学生-课程数据库中计算机系 CS 学生的学号、姓名及年龄。

  1. SELECT Sno, Sname, Age
  2. FROM S
  3. WHERE SD='CS';

注意,为了便于理解查询语句的结构,通常在写 SQL 语句时要将保留字(如 FROM 或 WHERE)作为每一行的开头。但是,如果一个查询或子查询非常短,可以直接将它们写在一行上,这种风格使得查询语句很紧凑,也具有很好的可读性。如上例也可写成如下形式:

  1. SELECT Sno, Sname, Age FROM S WHERE SD='CS';

【例 9.15】若当前年份为2017,查询学生的出生年份。

  1. SELECT Sno, 2017-Age FROM S;

3. 连接查询

若查询涉及两个以上的表,则称为连接查询。

【例 9.16】检索选修了课程号”C1”的学生的学号和姓名,可用连接查询和嵌套查询实现,方法如下:

  1. SELECT Sno, Sname
  2. FROM S, SC
  3. WHERE S.Sno=SC.Sno AND SC.Cno='C1';

【例 9.17】检索选修了课程名”MS”的学生的学号和姓名,可用连接查询和嵌套查询实现,方法如下:

  1. SELECT Sno, Sname
  2. FROM S, SC, C
  3. WHERE S.Sno=SC.Sno AND SC.Cno=C.Cno AND C.Cname='MS';

【例 9.18】检索至少选修了课程号”C1”和”C3”的学生的学号,实现方法如下:

  1. SELECT Sno
  2. FROM SC SCX, SC SCY
  3. WHERE SCX.Sno=SCY.Sno AND SCX.Cno='C1' AND SCY.Cno='C3';

4. 子查询与聚集函数

1)子查询

子查询也称嵌套查询。嵌套查询是指一个 SELECT-FROM-WHERE 查询块可以嵌入另一个查询块之中。在 SQL 中允许多重嵌套。

【例 9.19】例9.17可以采用嵌套查询来实现。

  1. SELECT Sno, Sname
  2. FROM S
  3. WHERE Sno IN (
  4. SELECT Sno
  5. FROM SC
  6. WHERE Cno IN (
  7. SELECT Cno
  8. FROM C
  9. WHERE Cname='MS'
  10. )
  11. );
2)聚集函数

聚集函数是以一个值的集合为输入,返回单个值的函数。SQL 提供了5个预定义聚集函数:平均值 AVG、最小值 MIN、最大值 MAX、求和 SUM 以及计数 COUNT,如表9-4所示。

表9-4 聚集函数的功能

聚集函数名 功能
COUNT([DISTINCT\ ALL]*) 统计元组个数
COUNT([DISTINCT\ ALL]<列名>) 统计一列中值的个数
SUM([DISTINCT\ ALL]<列名>) 计算一列(该列应为数值型)中值的总和
AVG([DISTINCT\ ALL]<列名>) 计算一列(该列应为数值型)值的平均值
MAX([DISTINCT\ ALL]<列名>) 求一列值的最大值
MIN([DISTINCT\ ALL]<列名>) 求一列值的最小值

使用 ANY 和 ALL 谓词必须同时使用比较运算符,其含义及等价的转换关系如表9-5所示。用聚集函数实现子查询通常比直接用 ALL 或 ANY 查询效率要高。

表9-5 ANY、ALL 谓词的含义及等价的转换关系

谓词 语义 等价转换关系
$>$ ANY 大于子查询结果中的某个值 $>$ MIN
$>$ ALL 大于子查询结果中的所有值 $>$ MAX
$<$ ANY 小于子查询结果中的某个值 $<$ MAX
$<$ ALL 小于子查询结果中的所有值 $<$ MIN
$\geq$ ANY 大于等于子查询结果中的某个值 $\geq$ MIN
$\geq$ ALL 大于等于子查询结果中的所有值 $\geq$ MAX
$\leq$ ANY 小于等于子查询结果中的某个值 $\leq$ MAX
$\leq$ ALL 小于等于子查询结果中的所有值 $\leq$ MIN
$<>$ ANY 不等于子查询结果中的某个值 —
$<>$ ALL 不等于子查询结果中的任何一个值 NOT IN
$=$ ANY 等于子查询结果中的某个值 IN
$=$ ALL 等于子查询结果中的所有值 —

【例 9.20】查询课程 C1 的最高分和最低分以及高低分之间的差距。

  1. SELECT MAX(G), MIN(G), MAX(G)-MIN(G)
  2. FROM Sc
  3. WHERE Cno='C1';

【例 9.21】查询其他系比计算机系 CS 所有学生年龄都要小的学生的姓名及年龄。

方法1:(用 ALL 谓词)

  1. SELECT Sname, Age
  2. FROM S
  3. WHERE Age < ALL (
  4. SELECT Age
  5. FROM S
  6. WHERE SD='CS'
  7. )
  8. AND SD <> 'CS';

方法2:(用 MIN 聚集函数)从等价的转换关系表9-5中可见,$<$ ALL 可用 $<$ MIN 代换。

  1. SELECT Sname, Age
  2. FROM S
  3. WHERE Age < (
  4. SELECT MIN(Age)
  5. FROM S
  6. WHERE SD='CS'
  7. )
  8. AND SD <> 'CS';

说明:方法2实际上是找出计算机系年龄最小的学生的年龄,只要其他系的学生年龄比这个年龄小,那么就应在结果集中。

【例 9.22】查询其他系比计算机系某一学生年龄小的学生的姓名及年龄。

方法1:(用 ANY 谓词)

  1. SELECT Sname, Age
  2. FROM S
  3. WHERE Age < ANY (
  4. SELECT Age
  5. FROM S
  6. WHERE SD='CS'
  7. )
  8. AND SD <> 'CS';

方法2:(用 MAX 聚集函数)从等价的转换关系表9-5中可以看到,$<$ ANY 可用 $<$ MAX 代换。

  1. SELECT Sname, Age
  2. FROM S
  3. WHERE Age < (
  4. SELECT MAX(Age)
  5. FROM S
  6. WHERE SD='CS'
  7. )
  8. AND SD <> 'CS';

说明:方法2实际上是找出计算机系年龄最大的学生的年龄,只要其他系的学生年龄比这个年龄大,那么就应在结果集中。

5. 分组查询

1)GROUP BY 子句

在 WHERE 子句后面加上 GROUP BY 子句可以对元组进行分组,保留字 GROUP BY 后面跟着一个分组属性列表。最简单的情况是 FROM 子句后面只有一个关系,根据分组属性对它的元组进行分组。SELECT 子句中使用的聚集操作符仅用在每个分组上。

【例 9.23】学生数据库中的 SC 关系,查询每个学生的平均成绩。

  1. SELECT Sno, AVG(Grade)
  2. FROM SC
  3. GROUP BY Sno;

该语句是将 SC 关系的元组重新组织并进行分组,使得不同学号的元组分别被组织在一起,求出各个学生的平均值并输出。

2)HAVING 子句

假如元组在分组前按照某种方式加上限制,使得不需要的分组为空,在 GROUP BY 子句后面跟一个 HAVING 子句即可。

注意:当元组含有空值时,应该记住以下两点。

(1)空值在任何聚集操作中被忽视。它对求和、求平均值和计数都没有影响。它也不能是某列的最大值或最小值。例如,COUNT(*)是某个关系中所有元组数目之和,但 COUNT(A)却是 A 属性非空的元组个数之和。

(2)NULL 值又可以在分组属性中看作是一个一般的值。例如,在 SELECT A, AVG(B) FROM R 中,当 A 的属性值为空时,就会统计 A=NULL 的所有元组中 B 的均值。

【例 9.24】供应商数据库中的 S、P、J、SPJ 关系,查询某工程至少用了三家供应商(包含三家)供应的零件的平均数量,并按工程号的降序排列。

  1. SELECT Jno, AVG(Qty)
  2. FROM SPJ
  3. GROUP BY Jno
  4. HAVING COUNT(DISTINCT(Sno)) > 2
  5. ORDER BY Jno DESC;

根据题意”某工程至少用了三家供应商(包含三家)供应的零件”,应该按照工程号分组,而且应该加上条件——供应商的数目。但是需要注意的是,一个工程项目可能用了同一个供应商的多种零件,因此,在统计供应商数的时候需要加上 DISTINCT,以避免重复统计导致错误的结果。

6. 更名运算

SQL 提供了可为关系和属性重新命名的机制,这是通过使用具有如下形式的 AS 子句来实现的:

  1. Old-name AS new-name

AS 子句既可出现在 SELECT 子句,也可出现在 FROM 子句中。

【例 9.25】查询计算机系学生的 Sname 和 Age,但 Sname 用”姓名”表示,Age 用”年龄”表示。其语句如下:

  1. SELECT Sname AS 姓名, Age AS 年龄
  2. FROM S
  3. WHERE Age < (
  4. SELECT MAX(Age)
  5. FROM S
  6. WHERE SD='CS'
  7. )
  8. AND SD <> 'CS';

SQL 中的元组变量必须和特定的关系相联系。元组变量是通过在 FROM 子句中使用 AS 子句来定义的。

【例 9.26】查询计算机系选修了 C1 课程的学生的姓名 Sname 和成绩 Grade。其语句如下:

  1. SELECT Sname, Grade
  2. FROM Students AS x, sc AS y
  3. WHERE x.sno=y.sno AND y.cno='C1';

元组变量在比较同一关系的两个元组时非常有用。

7. 字符串操作

对于字符串进行的最常用的操作是使用操作符 LIKE 的模式匹配。使用两个特殊的字符来描述模式:”%”匹配任意字符串;”_”匹配任意一个字符。模式是大小写敏感的。例如:

Marry% 匹配任何以 Marry 开头的字符串;%idge% 匹配任何包含 idge 的字符串,例如 Marryidge、Rock Ridge、Mianus Bridge 和 Ridgeway。

““匹配只含两个字符的字符串;”%_”匹配至少包含两个字符的字符串。

【例 9.27】学生关系模式为(Sno, Sname, Sex, SD, Age, Add),其中,Sno 为学号,Sname 为姓名,Sex 为性别,SD 为所在系,Age 为年龄,Add 为家庭住址。请查询:

(1)家庭住址包含”科技路”的学生的姓名。

(2)名字为”晓军”的学生的姓名、年龄和所在系。

解:(1)查询家庭住址包含”科技路”的学生的姓名的 SQL 语句如下:

  1. SELECT Sname
  2. FROM S
  3. WHERE Add LIKE '%科技路%';

(2)查询名字为”晓军”的学生的姓名、年龄和所在系的 SQL 语句如下:

  1. SELECT Sname, Age, SD
  2. FROM S
  3. WHERE Sname LIKE '_晓军';

为了使模式中包含特殊模式字符(即%和_),在 SQL 中允许使用 ESCAPE 关键词来定义转义符。转义符紧靠着特殊字符,并放在它的前面,表示该特殊字符被当成普通字符。例如,在 LIKE 比较中使用 ESCAPE 关键词来定义转义符,例如使用反斜杠”\”作为转义符。

  • LIKE 'ab\%cd%' ESCAPE '\',匹配所有以 ab%cd 开头的字符串。
  • LIKE 'ab\_cd%' ESCAPE '\',匹配所有以 ab_cd 开头的字符串。

8. 视图的查询

【例 9.28】建立”计算机系”(CS 表示计算机系)学生的视图,并要求进行修改、插入操作时保证该视图只有计算机系的学生。

  1. CREATE VIEW CS-STUDENT
  2. AS SELECT Sno, Sname, Sage, Sex
  3. FROM Student
  4. WHERE SD='CS'
  5. WITH CHECK OPTION;

此时查询计算机系年龄小于20岁的学生的学号及年龄的 SQL 语句如下:

  1. SELECT Sno, Age FROM CS-STUDENT WHERE SD='CS' AND Age<20;

系统执行该语句时,通常先将其转换成等价的对基本表的查询,然后执行查询语句。即当查询视图表时,系统先从数据字典中取出该视图的定义,然后将定义中的查询语句和对该视图的查询语句结合起来,形成一个修正的查询语句。对上例修正之后的查询语句为:

  1. SELECT Sno, Age FROM Student WHERE SD='CS' AND Age<20;

9.4.5 SQL 数据更新

1. 插入

如果要在关系数据库中插入数据,可以指定被插入的元组,或者用查询语句选出一批待插入的元组。插入语句的基本格式如下:

  1. INSERT INTO 基本表名 (字段名[,字段名]...)
  2. VALUES (常量[,常量]...);
  3. INSERT INTO 基本表名 (列表名)
  4. SELECT 查询语句;

【例 9.29】将学号为3002、课程号为 C4、成绩为98的元组插入 SC 关系中。其语句如下:

  1. INSERT INTO SC
  2. VALUES('3002', 'C4', 98);

【例 9.30】创建了一个新的视图 v_employees,该视图基于表 employees 创建。

  1. CREATE VIEW v_employees(number, name, age, sex, salary)
  2. AS
  3. SELECT number, name, age, sex, salary
  4. FROM employees
  5. WHERE name='张三';

通过执行以下语句使用 v_employees 视图向表 employees 中添加一条新的数据记录。

  1. INSERT INTO v_employees
  2. VALUES(001, '李力', 22, 'm', 2000);

2. 删除

  1. DELETE FROM 基本表名
  2. [WHERE 条件表达式];

【例 9.31】删除表 employees 中姓名为张然的记录。

  1. DELETE FROM employees
  2. WHERE name='张然';

3. 修改

  1. UPDATE 基本表名
  2. SET 列名=值表达式[,列名=值表达式...]
  3. [WHERE 条件表达式];

【例 9.32】将教师的工资增加5%。

  1. UPDATE teachers
  2. SET Salary = Salary * 1.05;

【例 9.33】将教师的工资少于1000的增加5%工资。

  1. UPDATE teachers
  2. SET Salary = Salary * 1.05
  3. WHERE Salary < 1000;

使用视图可以更新数据记录,但应该注意的是,更新的只是数据库中的基表。

【例 9.34】创建一个基于表 employees 的视图 v_employees,然后通过该视图修改表 employees 中的记录。其语句如下:

  1. CREATE VIEW v_employees
  2. AS
  3. SELECT * FROM employees;
  4. UPDATE v_employees
  5. SET name='张然'
  6. WHERE name='张三';

9.4.6 SQL 访问控制

数据控制控制的是用户对数据的存储权力,是由 DBA 决定的。但是,某个用户对某类数据具有何种权利,是个政策问题而不是技术问题。DBMS 的功能就是保证这些决定的执行。因此,DBMS 数据控制应具有以下功能。

(1)通过 GRANT 和 REVOKE 将授权通知系统,并存入数据字典。

(2)当用户提出请求时,根据授权情况检查是否执行操作请求。

SQL 标准包括 DELETE、INSERT、SELECT 和 UPDATE 权限。SELECT 权限对应于 READ 权限,SQL 还包括了 REFERENCES 权限,用来限制用户在创建关系时定义外码的能力。

1. 授权的语句格式

  1. GRANT <权限>[,<权限>]...[ON <对象类型> <对象名>] TO <用户>[,<用户>]...
  2. [WITH GRANT OPTION];

注意:不同类型的操作对象有不同的操作权限,常见的操作权限如表9-7所示。

表9-7 常见的操作权限

对象 对象类型 操作权限
属性列 TABLE SELECT、INSERT、UPDATE、DELETE、ALL PRIVILEGES(4种权限的总和)
视图 TABLE SELECT、INSERT、UPDATE、DELETE、ALL PRIVILEGES(4种权限的总和)
基本表 TABLE SELECT、INSERT、UPDATE、DELETE、ALTER、INDEX、ALL PRIVILEGES(6种权限的总和)
数据库 DATABASE CREATETAB 建立表的权限,可由 DBA 授予普通用户

说明如下。

  • PUBLIC:接受权限的用户可以是单个或多个具体的用户,PUBLIC 参数可将权限赋给全体用户。
  • WITH GRANT OPTION:若指定了此子句,那么获得了权限的用户还可以将权限赋给其他用户。

【例 9.35】如果用户要求给数据库 SPJ 中的供应商 S、零件 P、项目 J 表赋予各种权限。

(1)将对供应商 S、零件 P、项目 J 的所有操作权限赋给用户 User1 及 User2,其授权语句如下:

  1. GRANT ALL PRIVILEGES ON TABLE S, P, J TO User1, User2;

(2)将对供应商 S 的插入权限赋给用户 User1,并允许将此权限赋给其他用户,其授权语句如下:

  1. GRANT INSERT ON TABLE S TO User1 WITH GRANT OPTION;

9.4.7 嵌入式 SQL

SQL 提供了将 SQL 语句嵌入到某种高级语言中的使用方式,通常采用预编译的方法识别嵌入到高级语言中的 SQL 语句。该方法的关键问题是必须区分主语言中嵌入的 SQL 语句,以及主语言和 SQL 间的通信问题。为了区分主语言与 SQL 语言,需要在所有的 SQL 语句前加前缀 EXEC SQL,而 SQL 的结束标志随主语言的不同而不同。

例如,PL/I 和 C 语言的引用格式为:

  1. EXEC SQL <SQL 语句>;

又如,COBOL 语言的引用格式为:

  1. EXEC SQL <SQL 语句> END-EXEC

嵌入式 SQL 与主语言之间的通信通常有以下 3 种方式。

(1) SQL 通信区(SQL Communication Area,SQLCA)向主语言传递 SQL 语句执行的状态信息,使主语言能够根据此信息控制程序流程。

(2) 主变量也称共享变量。主语言向 SQL 语句提供参数主要通过主变量,主变量由主语言的程序定义,并用 SQL 的 DECLARE 语句说明。在引用时,为了与 SQL 属性名相区别,需要在主变量前加 :。

【例 9.37】根据共享变量 givensno 的值,查询学生关系 students 中学生的姓名、年龄和性别。

  1. EXEC SQL SELECT sname, age, sex
  2. INTO :Msname, :Mage, :Msex
  3. FROM students
  4. WHERE sno = :givensno;

(3) 游标 SQL 语言是面向集合的,一条 SQL 语句可产生或处理多条记录,而主语言是面向记录的,一组主变量一次只能放一条记录。所以,引入游标,通过移动游标指针来决定获取哪一条记录。

9.5 关系数据库的规范化

在关系模型中,一个数据库模式是关系模式的集合。关系数据理论是指导数据库设计的基础,关系数据库设计是数据库语义学的问题。通常,要保证构造的关系既能准确地反映现实世界,又有利于应用和具体的操作。关系数据库设计理论的核心是数据间的函数依赖,衡量的标准是关系规范化的程度及分解的无损连接和保持函数依赖性。关系数据库设计的目标是生成一组合适的、性能良好的关系模式,以减少系统中信息存储的冗余度,并可方便地获取信息。

9.5.1 函数依赖

数据依赖是通过一个关系中属性间值的相等与否体现出来的数据间的相互关系,是现实世界属性间联系和约束的抽象,是数据内在的性质,是语义的体现。函数依赖则是一种最重要、最基本的数据依赖。

(1) 函数依赖。设 $R(U)$ 是属性集 $U$ 上的关系模式,$X$、$Y$ 是 $U$ 的子集。若对 $R(U)$ 的任何一个可能的关系 $r$,$r$ 中不可能存在两个元组在 $X$ 上的属性值相等,而在 $Y$ 上的属性值不等,则称 $X$ 函数决定 $Y$ 或 $Y$ 函数依赖于 $X$,记作 $X \to Y$。

(2) 非平凡的函数依赖。如果 $X \to Y$,但 $Y \not\subseteq X$,则称 $X \to Y$ 是非平凡的函数依赖。一般情况下,总是讨论非平凡的函数依赖。

(3) 平凡的函数依赖。如果 $X \to Y$,但 $Y \subseteq X$,则称 $X \to Y$ 是平凡的函数依赖。

(4) 完全函数依赖。在 $R(U)$ 中,如果 $X \to Y$,并且对于 $X$ 的任何一个真子集 $X’$ 都有 $X’$ 不能决定 $Y$,则称 $Y$ 对 $X$ 完全函数依赖,记作 $X \stackrel{f}{\longrightarrow} Y$。

例如,给定一个学生选课关系 $SC(Sno, Cno, G)$,可以得到 $F = {(Sno, Cno) \to G}$,对 $(Sno, Cno)$ 中的任何一个真子集 $Sno$ 或 $Cno$ 都不能决定 $G$,所以,$G$ 完全依赖于 $Sno$、$Cno$。

(5) 部分函数依赖。如果 $X \to Y$,但 $Y$ 不完全函数依赖于 $X$,则称 $Y$ 对 $X$ 部分函数依赖,记作 $X \stackrel{p}{\longrightarrow} Y$。部分函数依赖也称为局部函数依赖。

(6) 传递依赖。在 $R(U, F)$ 中,如果 $X \to Y$,$Y \not\subseteq X$,$Y \to Z$,则称 $Z$ 对 $X$ 传递依赖。

(7) 码。设 $K$ 为 $R(U, F)$ 中属性的组合,若 $K \to U$,且对于 $K$ 的任何一个真子集 $K’$ 都有 $K’$ 不能决定 $U$,则 $K$ 为 $R$ 的候选码。若有多个候选码,则选一个作为主码。候选码通常也称为候选关键字。

(8) 主属性和非主属性。包含在任何一个候选码中的属性称为主属性,否则称为非主属性。

(9) 外码。若 $R(U)$ 中的属性或属性组 $X$ 非 $R$ 的码,但 $X$ 是另一个关系的码,则称 $X$ 为外码。

(10) 函数依赖的公理系统(Armstrong 公理系统)。设关系模式 $R(U, F)$,其中 $U$ 为属性集,$F$ 是 $U$ 上的一组函数依赖,那么有以下推理规则。

  • A1 自反律:若 $Y \subseteq X \subseteq U$,则 $X \to Y$ 为 $F$ 所蕴涵。
  • A2 增广律:若 $X \to Y$ 为 $F$ 所蕴涵,且 $Z \subseteq U$,则 $XZ \to YZ$ 为 $F$ 所蕴涵。
  • A3 传递律:若 $X \to Y$,$Y \to Z$ 为 $F$ 所蕴涵,则 $X \to Z$ 为 $F$ 所蕴涵。

根据上述 3 条推理规则又可推出下述 3 条推理规则。

  • 合并规则:若 $X \to Y$,$X \to Z$,则 $X \to YZ$ 为 $F$ 所蕴涵。
  • 伪传递率:若 $X \to Y$,$WY \to Z$,则 $XW \to Z$ 为 $F$ 所蕴涵。
  • 分解规则:若 $X \to Y$,$Z \subseteq Y$,则 $X \to Z$ 为 $F$ 所蕴涵。

9.5.2 规范化

关系数据库设计的方法之一就是设计满足适当范式的模式,通常可以通过判断分解后的模式达到几范式来评价模式规范化的程度。范式有 1NF、2NF、3NF、BCNF、4NF 和 5NF,其中 1NF 的级别最低。这几种范式之间,$5NF \subset 4NF \subset BCNF \subset 3NF \subset 2NF \subset 1NF$ 成立。通过分解,可以将一个低一级范式的关系模式转换成若干个高一级范式的关系模式,这个过程称为规范化。下面给出 1NF、2NF 和 3NF 的定义。

1. 1NF(第一范式)

定义:若关系模式 $R$ 的每一个分量是不可再分的数据项,则关系模式 $R$ 属于第一范式。

例如,供应者和它所提供的零件信息,关系模式 FIRST 和函数依赖集 $F$ 如下:

$$ \text{FIRST}(Sno, Sname, Status, City, Pno, Qty) $$

$$ F = {Sno \to Sname, Sno \to Status, Status \to City, (Sno, Pno) \to Qty} $$

若具体的关系如表 9-8 所示。从表 9-8 可以看出,每一个分量都是不可再分的数据项,所以是 1NF 的。但是,1NF 存在以下 4 个问题。

(1) 冗余度大。例如,每个供应者的 $Sno$、$Sname$、$Status$、$City$ 要与其供应的零件的种类一样多。

(2) 引起修改操作的不一致性。例如,供应者 S1 从”天津”搬到”上海”,若稍不注意,就会使一些数据被修改,另一些数据没有被修改,导致数据修改的不一致性。

(3) 插入异常。关系模式 FIRST 的主码为 $Sno$、$Pno$,按照关系模式实体完整性规定,主码不能取空值或部分取空值。这样,当某个供应者的某些信息未提供时(如 $Pno$),则不能进行插入操作,这就是所谓的插入异常。

(4) 删除异常。若供应商 S4 的 P2 零件销售完了,并且以后不再销售 P2 零件,那么应删除该元组。这样,在基本关系 FIRST 找不到 S4,而 S4 又是客观存在的。

正因为上述 4 个原因,所以要对模式进行分解,并引入了 2NF。

2. 2NF(第二范式)

定义:若关系模式 $R \in 1NF$,且每一个非主属性完全依赖于码,则关系模式 $R \in 2NF$。

换句话说,当 1NF 消除了非主属性对码的部分函数依赖,则称为 2NF。

例如,FIRST 关系中的码是 $Sno$、$Pno$,而 $Sno \to Status$,因此非主属性 $Status$ 部分函数依赖于码,故非 2NF 的。

若此时将 FIRST 关系分解为 FIRST1($Sno$, $Sname$, $Status$, $City$) 和 FIRST2($Sno$, $Pno$, $Qty$)。其中,FIRST1 $\in$ 2NF,FIRST2 $\in$ 2NF。因为分解后的关系模式 FIRST1 的码为 $Sno$,非主属性 $Sname$、$Status$、$City$ 完全依赖于码 $Sno$,所以属于 2NF;关系模式 FIRST2 的码为 $Sno$、$Pno$,非主属性 $Qty$ 完全依赖于码,所以也属于 2NF。

3. 3NF(第三范式)

定义:若关系模式 $R(U, F)$ 中若不存在这样的码 $X$,属性组 $Y$ 及非主属性 $Z$($Z \not\subseteq Y$)使得 $X \to Y$($Y \nleftarrow X$),$Y \to Z$ 成立,则关系模式 $R \in 3NF$。

即当 2NF 消除了非主属性对码的传递函数依赖,则称为 3NF。

例如,FIRST1 $\notin$ 3NF,因为在分解后的关系模式 FIRST1 中有 $Sno \to Status$,$Status \to City$,存在着非主属性 $City$ 传递依赖于码 $Sno$。若此时将 FIRST1 继续分解为:

  • FIRST11($Sno$, $Sname$, $Status$) $\in$ 3NF
  • FIRST12($Status$, $City$) $\in$ 3NF

通过上述分解,数据库模式 FIRST 转换为 FIRST11($Sno$,$Sname$,$Status$)、FIRST12($Status$,$City$) 和 FIRST2($Sno$,$Pno$,$Qty$) 3 个子模式。由于这 3 个子模式都达到了 3NF,因此称分解后的数据库模式达到了 3NF。

可以证明,3NF 的模式必是 2NF 的模式。产生冗余和异常的两个重要原因是部分依赖和传递依赖。因为 3NF 模式中不存在非主属性对码的部分函数依赖和传递函数依赖,所以具有较好的性能。对于非 3NF 的 1NF、2NF,其性能弱,一般不宜作为数据库模式,通常要将它们变换成为 3NF 或更高级别的范式,这个变换过程称为”关系模式的规范化处理”。

9.5.3 模式分解及分解应具有的特性

1. 分解

定义:关系模式 $R(U, F)$ 的一个分解是指 $\rho = {R1(U_1, F_1), R_2(U_2, F_2), \cdots, R_n(U_n, F_n)}$,其中,$U = \bigcup{i=1}^{n} U_i$,并且没有 $U_i \subseteq U_j, 1 \leq i, j \leq n$;$F_i$ 是 $F$ 在 $U_i$ 上的投影,$F_i = {X \to Y \mid X \to Y \in F^+ \wedge XY \subseteq U_i}$。

对一个给定的模式进行分解,使得分解后的模式是否与原来的模式等价有 3 种情况。

(1) 分解具有无损连接性。 (2) 分解要保持函数依赖。 (3) 分解既要无损连接性,又要保持函数依赖。

2. 无损连接

定义:$\rho = {R1(U_1, F_1), R_2(U_2, F_2), \cdots, R_k(U_k, F_k)}$ 是关系模式 $R(U, F)$ 的一个分解,若对 $R(U, F)$ 的任何一个关系 $r$ 均有 $r = m\rho(r)$ 成立,则分解 $\rho$ 具有无损连接性(简称无损分解),其中,$m\rho(r) = \bowtie{i=1}^{k} \pi_{R_i}(r)$。

定理:关系模式 $R(U, F)$ 的一个分解 $\rho = {R_1(U_1, F_1), R_2(U_2, F_2)}$ 具有无损连接的充分必要的条件是 $U_1 \cap U_2 \to U_1 - U_2 \in F^+$ 或 $U_1 \cap U_2 \to U_2 - U_1 \in F^+$,证明略。

3. 保持函数依赖

定义:设关系模式 $R(U, F)$ 的一个分解 $\rho = {R1(U_1, F_1), R_2(U_2, F_2), \cdots, R_k(U_k, F_k)}$,如果 $F^+ = (\bigcup{i=1}^{k} \pi_{R_i}(F^+))$,则称分解 $\rho$ 保持函数依赖。

9.6 数据库的控制功能

9.6.1 事务管理

事务是一个操作序列,这些操作”要么都做,要么都不做”,是数据库环境中不可分割的逻辑工作单位。事务和程序是两个不同的概念,一般一个程序可包含多个事务。在 SQL 语言中,事务定义的语句有以下三条。

(1) BEGIN TRANSACTION:事务开始。 (2) COMMIT:事务提交。该操作表示事务成功地结束,它将通知事务管理器该事务的所有更新操作现在可以被提交或永久地保留。 (3) ROLLBACK:事务回滚。该操作表示事务非成功地结束,它将通知事务管理器出故障了,数据库可能处于不一致状态,该事务的所有更新操作必须回滚或撤销。

事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这 4 个特性也称事务的 ACID 性质。

(1) 原子性。事务是原子的,要么都做,要么都不做。

(2) 一致性。事务执行的结果必须保证数据库从一个一致性状态变到另一个一致性状态。因此,当数据库只包含成功事务提交的结果时,称数据库处于一致性状态。

(3) 隔离性。事务相互隔离。当多个事务并发执行时,任一事务的更新操作直到其成功提交的整个过程,对其他事务都是不可见的。

(4) 持久性。一旦事务成功提交,即使数据库崩溃,其对数据库的更新操作也将永久有效。

9.6.2 数据库的备份与恢复

在数据库的运行过程中,难免会出现计算机系统的软、硬件故障,这些故障会影响数据库中数据的正确性,甚至破坏数据库,使数据库中的全部或部分数据丢失。因此,数据库的关键技术在于建立冗余数据,即备份数据。如何在系统出现故障后能够及时地使数据库恢复到故障前的正确状态,就是数据库恢复技术。

1. 故障类型

数据库中的 4 类故障是事务内部故障、系统故障、介质故障及计算机病毒。

(1) 事务内部故障。事务内部的故障有的可以通过事务程序本身发现。例如,银行转账事务,将账户 A 的金额转 $X$ 到账户 B,此时应该将账户 A 的余额 $-X$,将账户 B 的余额 $+X$。如果账户 A 的余额不足,那么,两个事务都不做,否则都做。但有些是非预期的,不能由事务程序处理,例如运算溢出、并发事务发生死锁等。

(2) 系统故障。通常称为软故障,是指造成系统停止运行的任何事件,使得系统要重新启动,例如 CPU 故障、操作系统故障和突然停电等。

(3) 介质故障。通常称为硬故障,如磁盘损坏、磁头碰撞和瞬时强磁干扰。此类故障发生的几率小,但破坏性最大。

(4) 计算机病毒。计算机病毒是一种人为的故障和破坏,是在计算机程序中插入的破坏,计算机功能或者数据可以繁殖和传播的一组计算机指令或程序代码。

2. 备份方法

恢复的基本原理是”建立数据冗余”(重复存储)。建立冗余数据的方法是进行数据转储和登记日志文件。数据的转储分为静态转储和动态转储、海量转储和增量转储、日志文件。

(1) 静态转储和动态转储。静态转储是指在转储期间不允许对数据库进行任何存取、修改操作;动态转储是在转储期间允许对数据库进行存取、修改操作。因此,转储和用户事务可并发执行。

(2) 海量转储和增量转储。海量转储是指每次转储全部数据;增量转储是指每次只转储上次转储后更新过的数据。

(3) 日志文件。在事务处理的过程中,DBMS 把事务开始、事务结束以及对数据库的插入、删除和修改的每一次操作写入日志文件。一旦发生故障,DBMS 的恢复子系统利用日志文件撤销事务对数据库的改变,回退到事务的初始状态。因此,DBMS 利用日志文件来进行事务故障恢复和系统故障恢复,并可协助后备副本进行介质故障恢复。

3. 恢复

事务恢复有以下 3 个步骤。

(1) 反向扫描文件日志(即从最后向前扫描日志文件),查找该事务的更新操作。 (2) 对事务的更新操作执行逆操作。 (3) 继续反向扫描日志文件,查找该事务的其他更新操作,并做同样的处理,直到事务的开始标志。

4. 数据库镜像

为了避免磁盘介质出现故障影响数据库的可用性,许多 DBMS 提供数据库镜像功能用于数据库恢复。需要说明的是,数据库镜像是通过复制数据实现的,但频繁地复制数据会降低系统的运行效率。因此,在实际应用中往往对关键的数据和日志文件镜像。

9.6.3 并发控制

所谓并发操作,是指在多用户共享的系统中许多用户可能同时对同一数据进行操作。并发操作带来的问题是数据的不一致性,主要有三类:丢失更新、不可重复读和读脏数据。其主要原因是事务的并发操作破坏了事务的隔离性。DBMS 的并发控制子系统负责协调并发事务的执行,保证数据库的完整性不受破坏,避免用户得到不正确的数据。

1. 并发操作带来的问题

并发操作带来的数据不一致性有三类:丢失修改、不可重复读和读脏数据。

(1) 丢失修改。事务 $T_1$、$T_2$ 都是对数据 A 做减 1 操作。事务 $T_1$ 在时刻 $t_5$ 把 A 修改后的值 15 写入数据库,但事务 $T_2$ 在时刻 $t_7$ 再把它对 A 减 1 后的值 15 写入。两个事务都是对 A 的值进行减 1 操作并且都执行成功,但 A 中的值却只减了 1。例如火车售票系统,$T_1$ 与 $T_2$ 各售出了一张票,但数据库里的存票却只减了一张,造成数据的不一致。原因在于 $T_1$ 事务对数据库的修改被 $T_2$ 事务覆盖而丢失了,破坏了事务的隔离性。

(2) 不可重复读。事务 $T_1$ 读取 A、B 的值后进行运算,事务 $T_2$ 在 $t_6$ 时刻对 B 的值做了修改以后,事务 $T_1$ 又重新读取 A、B 的值再运算,同一事务内对同一组数据的相同运算结果不同,显然与事实不相符。同样是事务 $T_2$ 干扰了事务 $T_1$ 的独立性。

(3) 读脏数据。事务 $T_1$ 对数据 C 修改之后,在 $t_4$ 时刻事务 $T_2$ 读取修改后的 C 值做处理,之后事务 $T_1$ 回滚,数据 C 恢复了原来的值,事务 $T_2$ 对 C 所做的处理是无效的,它读的是被丢掉的垃圾值。

通过以上 3 个例子,在事务并行处理的过程中对相同数据进行访问导致了数据的不一致性,解决该问题可以从保证事务的隔离性入手。

2. 并发控制技术

并发控制的主要技术是封锁。基本封锁的类型有排它锁(简称 X 锁或写锁)和共享锁(简称 S 锁或读锁)。

1) 封锁

(1) 排它锁。若事务 T 对数据对象 A 加上 X 锁,则只允许 T 读取和修改 A,其他事务都不能再对 A 加任何类型的锁,直到 T 释放 A 上的锁。

(2) 共享锁。若事务 T 对数据对象 A 加上 S 锁,则只允许 T 读取 A,但不能修改 A,其他事务只能再对 A 加 S 锁,直到 T 释放 A 上的 S 锁。这就保证了其他事务可以读 A,但在 T 释放 A 上的 S 锁之前不能对 A 进行任何修改。

2) 三级封锁协议

(1) 一级封锁协议。事务在修改数据 R 之前必须先对其加 X 锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。一级封锁协议可以解决丢失更新问题。

(2) 二级封锁协议。在一级封锁协议的基础上,加上事务 T 在读数据 R 之前必须先对其加 S 锁,读完后即可释放 S 锁。二级封锁协议可以解决读脏数据的问题。但是,由于二级封锁协议读完了数据后即可释放 S 锁,所以不能保证可重复读。

(3) 三级封锁协议。在一级封锁协议的基础上,加上事务 T 在读数据 R 之前必须先对其加 S 锁,直到事务结束时释放 S 锁。三级封锁协议除了防止丢失修改和不读”脏”数据外,还进一步防止了不可重复读。

3. 活锁与死锁

所谓活锁,是指当事务 $T_1$ 封锁了数据 R 时,事务 $T_2$ 请求封锁数据 R,于是 $T_2$ 等待,当 $T_1$ 释放了 R 上的封锁后,系统首先批准了 $T_3$ 请求,于是 $T_2$ 仍等待,当 $T_3$ 释放了 R 上的封锁后,又批准了 $T_4$ 请求,依此类推,使得 $T_2$ 可能永远等待的现象。

所谓死锁,是指两个以上的事务分别请求封锁对方已经封锁的数据,导致了长期等待而无法继续运行下去的现象。

4. 并发调度的可串行性

多个事务的并发执行是正确的,当且仅当其结果与某一次序串行地执行它们时的结果相同,称这种调度策略是可串行化的调度。

可串行性是并发事务正确性的准则,按这个准则规定,一个给定的并发调度,当且仅当它是可串行化的才认为是正确调度。

5. 两段封锁协议

所谓两段封锁协议,是指所有事务必须分两个阶段对数据项加锁和解锁。即事务分两个阶段,第一阶段是获得封锁,事务可以获得任何数据项上的任何类型的锁,但不能释放;第二阶段是释放封锁,事务可以释放任何数据项上的任何类型的锁,但不能申请。

6. 封锁的粒度

封锁对象的大小称为封锁的粒度。封锁的对象可以是逻辑单元(如属性、元组、关系、索引项、整个索引甚至整个数据库),也可以是物理单元(如数据页或索引页)。