-->

数据库系统概论网络课程

数据库系统概论网络课程

  

   
   随着信息技术的发展,数据库在各行各业得到广泛的应用。数据库技术是计算机科学的重要分支,是信息技术的核心和基础。教育部将《数据库系统概论》列为本科计算机专业、信息系统和信息管理等专业的必修课。我们选择《数据库系统概论》精品课程教材建设,其目的为了加快高校数据库课程体系和教学内容改革的步伐,创新教育模式,努力提高教学水平和教育质量。

  为使《数据库系统概论》精品课程教材建设,反映数据库课程建设与学科发展最新成果和最高水平,体现现代教育思想,使其具有先进性、科学性和教育教学的适用性,我们将充分运用计算机人机交互辅助教学、计算机网络等现代教育技术、方法与手段,形成以立体化形式呈现的教材体系:形成纸质(教材、教学参考书),音像制品,电子、网络出版物(电子教案、多媒体CAI),与学科网站有机配套;通过教学平台,为教师教学、学生自主学习,提供完整的教学解决方案,最大限度地满足教学需要。

第一章 绪论

 

第一节 数据库系统概述

 

  1.1.1 数据、数据库、数据库管理系统、数据库系统

  数据、数据库、数据库管理系统和数据库系统是与数据库技术密切相关的四个基本概念。

  一、数据(DATA

  数据是数据库中存储的基本对象。数据在大多数人头脑中的第一个反应就是数字。其实数字只是最简单的一种数据,是数据的一种传统和狭义的理解。广义的理解,数据的种类很多,文字、图形、图像、声音、学生的档案记录、货物的运输情况等,这些都是数据。

  

  可以对数据做如下定义:描述事物的符号记录称为数据。描述事物的符号可以是数字,也可以是文字、图形、图像、声音、语言等,数据有多种表现形式,它们都可以经过数字化后存入计算机。

  为了了解世界,交流信息,人们需要描述这些事物。在日常生活中直接用自然语言(如汉语)描述。在计算机中,为了存储和处理这些事物,就要抽出对这些事物感兴趣的特征组成一个记录来描述。例如:在学生档案中,如果人们最感兴趣的是学生的姓名、性别、年龄、出生年月、籍贯、所在系别、入学时间,那么可以这样描述:

  (李明,男,211972,江苏,计算机系,1990

  因此这里的学生记录就是数据。对于上面这条学生记录,了解其含义的人会得到如下信息:李明是个大学生,1972年出生,男,江苏人,1990年考入计算机系;而不了解其语义的人则无法理解其含义。可见,数据的形式还不能完全表达其内容,需要经过解释。所以数据和关于数据的解释是不可分的,数据的解释是指对数据含义的说明,数据的含义称为数据的语义,数据与其语义是不可分的。

  二、数据库(DataBase,简称DB

  数据库,顾名思义,是存放数据的仓库。只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的。

  人们收集并抽取出一个应用所需要的大量数据之后,应将其保存起来以供进一步加工处理,进一步抽取有用信息。在科学技术飞速发展的今天,人们的视野越来越广,数据量急剧增加。过去人们把数据存放在文件柜里,现在人们借助计算机和数据库技术科学地保存和管理大量的复杂的数据,以便能方便而充分地利用这些宝贵的信息资源。

  所谓数据库是长期储存在计算机内、有组织的、可共享的数据集合。数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种用户共享。

  三、数据库管理系统(DataBase Management System,简称DBMS

  了解了数据和数据库的概念,下一个问题就是如何科学地组织和存储数据,如何高效地获取和维护数据。完成这个任务的是一个系统软件——数据库管理系统。

  数据库管理系统是位于用户与操作系统之间的一层数据管理软件。它的主要功能包括以下几个方面:

  1. 数据定义功能

  DBMS提供数据定义语言(Data Definition Language,简称DDL),用户通过它可以方便地定义对数据库中的数据对象进行定义。

  2. 数据操纵功能

  DBMS还提供数据操纵语言(Data Manipulation Language,简称DML),用户可以使用DML操纵数据实现对数据库的基本操作,如查询、插入、删除和修改等。

  3. 数据库的运行管理

  数据库在建立、运用和维护时由数据库管理系统统一管理、统一控制,以保证数据的安全性、完整性、多用户对数据的并发使用及发生故障后的系统恢复。

  4. 数据库的建立和维护功能

  它包括数据库初始数据的输入、转换功能,数据库的转储、恢复功能,数据库的重组织功能和性能监视、分析功能等。 这些功能通常是由一些实用程序完成的。

  数据库管理系统是数据库系统的一个重要组成部分。

  四、数据库系统(DataBase System,简称DBS

  数据库系统是指在计算机系统中引入数据库后的系统构成,一般由数据库、数据库管理系统(及其开发工具)、应用系统、数据库管理员和用户构成。应当指出的是,数据库的建立、使用和维护等工作只靠一个DBMS远远不够,还要有专门的人员来完成,这些人被称为数据库管理员(Data Base Administrator,简称DBA)。

  在一般不引起混淆的情况下常常把数据库系统简称为数据库。

  1.1.2 数据管理技术的产生和发展

  数据库技术是应数据管理任务的需要而产生的。

  数据的处理是指对各种数据进行收集、存储、加工和传播的一系列活动的总和。数据管理则是指对数据进行分类、组织、编码、存储、检索和维护,它是数据处理的中心问题。

  人们借助计算机进行数据处理是近三十年的事。研制计算机的初衷是利用它进行复杂的科学计算。随着计算机技术的发展,其应用远远地超出了这个范围。在应用需求的推动下,在计算机硬件、软件发展的基础上,数据管理技术经历了人工管理、文件系统、数据库系统三个阶段。

  1.1.3 数据库系统的特点

  与人工管理和文件系统相比,数据库系统的特点主要有以下几个方面。

  一、数据结构化

  数据结构化是数据库与文件系统的根本区别。

  在文件系统中,相互独立的文件的记录内部是有结构的。传统文件的最简单形式是等长同格式的记录集合。

  二、数据的共享性高,冗余度低,易扩充

  数据库系统从整体角度看待和描述数据,数据不再面向某个应用而是面向整个系统,因此数据可以被多个用户、多个应用共享使用。数据共享可以大大减少数据冗余,节约存储空间。数据共享还能够避免数据之间的不相容性与不一致性。

  所谓数据的不一致性是指同一数据不同拷贝的值不一样。采用人工管理或文件系统管理时,由于数据被重复存储,当不同的应用使用和修改不同的拷贝时就很容易造成数据的不一致。在数据库中数据共享,减少了由于数据冗余造成的不一致现象。

  由于数据面向整个系统,是有结构的数据,不仅可以被多个应用共享使用,而且容易增加新的应用,这就使得数据库系统弹性大,易于扩充,可以适应各种用户的要求。可以取整体数据的各种子集用于不同的应用系统,当应用需求改变或增加时,只要重新选取不同的子集或加上一部分数据便可以满足新的需求。

  三、数据独立性高

  数据独立性是数据库领域中一个常用术语,包括数据的物理独立性和数据的逻辑独立性。

  物理独立性是指用户的应用程序与存储在磁盘上的数据库中数据是相互独立的。也就是说,数据在磁盘上的数据库中怎样存储是由DBMS管理的,用户程序不需要了解,应用程序要处理的只是数据的逻辑结构,这样当数据的物理存储改变了,应用程序不用改变。

  逻辑独立性是指用户的应用程序与数据库的逻辑结构是相互独立的,也就是说,数据的逻辑结构改变了,用户程序也可以不变。

  数据独立性是由DBMS的二级映象功能来保证的,将在下面讨论。

  数据与程序的独立,把数据的定义从程序中分离出去,加上数据的存取又由DBMS负责,从而简化了应用程序的编制,大大减少了应用程序的维护和修改。

  四、数据由DBMS统一管理和控制

  数据库的共享是并发的(Concurrency)共享,即多个用户可以同时存取数据库中的数据甚至可以同时存取数据库中同一个数据。

  为此,DBMS还必须提供以下几方面的数据控制功能:

  (1 数据的安全性(Security)保护

  数据的安全性是指保护数据以防止不合法的使用造成的数据的泄密和破坏。使每个用户只能按规定,对某些数据以某些方式进行使用和处理。

  (2 数据的完整性(Integrity)检查

  数据的完整性指数据的正确性、有效性和相容性。完整性检查将数据控制在有效的范围内,或保证数据之间满足一定的关系。

  (3 并发(Concurrency)控制

  当多个用户的并发进程同时存取、修改数据库时,可能会发生相互干扰而得到错误的结果或使得数据库的完整性遭到破坏,因此必须对多用户的并发操作加以控制和协调。

  (4 数据库恢复(Recovery

  计算机系统的硬件故障、软件故障、操作员的失误以及故意的破坏也会影响数据库中数据的正确性,甚至造成数据库部分或全部数据的丢失。DBMS必须具有将数据库从错误状态恢复到某一已知的正确状态(亦称为完整状态或一致状态)的功能,这就是数据库的恢复功能。

  综上所述,数据库是长期存储在计算机内有组织的大量的共享的数据集合。它可以供各种用户共享,具有最小冗余度和较高的数据独立性。DBMS在数据库建立、运用和维护时对数据库进行统一控制,以保证数据的完整性、安全性,并在多用户同时使用数据库时进行并发控制,在发生故障后对系统进行恢复。

  数据库系统的出现使信息系统从以加工数据的程序为中心转向围绕共享的数据库为中心的新阶段。这样既便于数据的集中管理,又有利于应用程序的研制和维护,提高了数据的利用率和相容性,提高了决策的可靠性。

  

  目前,数据库已经成为现代信息系统的不可分离的重要组成部分。具有数百万甚至数十亿字节信息的数据库已经普遍存在于科学技术、工业、农业、商业、服务业和政府部门的信息系统。20世纪80年代后不仅在大型机上,在多数微机上也配置了DBMS,使数据库技术得到更加广泛的应用和普及。

  数据库技术是计算机领域中发展最快的技术之一。数据库技术的发展是沿着数据模型的主线展开的。下面讨论数据模型。

 

第一章 绪论

 

第二节 数据模型

 

  模型,特别是具体模型,人们并不陌生。一张地图,一组建筑设计沙盘,一架精致的航模飞机都是具体的模型。一眼望去,就会使人联想到真实生活中的事物。模型是现实世界特征的模拟和抽象。数据模型(Data Model)也是一种模型,它是现实世界数据特征的抽象。

  数据库是某个企业、组织或部门所涉及的数据的综合,它不仅要反映数据本身的内容,而且要反映数据之间的联系。由于计算机不可能直接处理现实世界中的具体事物,所以人们必须事先把具体事物转换成计算机能够处理的数据。在数据库中用数据模型这个工具来抽象、表示和处理现实世界中的数据和信息。通俗地讲数据模型就是现实世界的模拟。

  现有的数据库系统均是基于某种数据模型的。因此,了解数据模型的基本概念是学习数据库的基础。

  数据模型应满足三方面要求:一是能比较真实地模拟现实世界;二是容易为人所理解;三是便于在计算机上实现。一种数据模型要很好地满足这三方面的要求在目前尚很困难。在数据库系统中针对不同的使用对象和应用目的,采用不同的数据模型。

  不同的数据模型实际上是提供给我们模型化数据和信息的不同工具。根据模型应用的不同目的,可以将这些模型划分为两类,它们分属于两个不同的层次。

  第一类模型是概念模型,也称信息模型,它是按用户的观点来对数据和信息建模,主要用于数据库设计。另一类模型是数据模型,主要包括网状模型、层次模型、关系模型等,它是按计算机系统的观点对数据建模,主要用于DBMS的实现。

  数据模型是数据库系统的核心和基础。各种机器上实现的DBMS软件都是基于某种数据模型的。

  为了把现实世界中的具体事物抽象、组织为某一DBMS支持的数据模型,人们常常首先将现实世界抽象为信息世界,然后将信息世界转换为机器世界。也就是说,首先把现实世界中的客观对象抽象为某一种信息结构,这种信息结构并不依赖于具体的计算机系统,不是某一个DBMS支持的数据模型,而是概念级的模型;然后再把概念模型转换为计算机上某一DBMS支持的数据模型。

  1.2.1 数据模型的组成要素

  一般地讲,数据模型是严格定义的一组概念的集合。这些概念精确地描述了系统的静态特性、动态特性和完整性约束条件。因此数据模型通常由数据结构、数据操作和完整性约束三部分组成。

  一、数据结构

  数据结构是所研究的对象类型的集合。这些对象是数据库的组成成分,它们包括两类,一类是与数据类型、内容、性质有关的对象,例如网状模型中的数据项、记录,关系模型中的域、属性、关系等;一类是与数据之间联系有关的对象,例如网状模型中的系型(Set Type)。

  数据结构是刻画一个数据模型性质最重要的方面。因此在数据库系统中,人们通常按照其数据结构的类型来命名数据模型。例如层次结构、网状结构和关系结构的数据模型分别命名为层次模型、网状模型和关系模型。

  数据结构是对系统静态特性的描述。

  二、数据操作

  数据操作是指对数据库中各种对象(型)的实例(值)允许执行的操作的集合,包括操作及有关的操作规则。数据库主要有检索和更新(包括插入、删除、修改)两大类操作。数据模型必须定义这些操作的确切含义、操作符号、操作规则(如优先级)以及实现操作的语言。数据操作是对系统动态特性的描述。

  三、数据的约束条件

  数据的约束条件是一组完整性规则的集合。完整性规则是给定的数据模型中数据及其联系所具有的制约和依存规则,用以限定符合数据模型的数据库状态以及状态的变化,以保证数据的正确、有效、相容。

  数据模型应该反映和规定本数据模型必须遵守的基本的通用的完整性约束条件。例如,在关系模型中,任何关系必须满足实体完整性和参照完整性两个条件(第二章将详细讨论这两个完整性约束条件)。

  此外,数据模型还应该提供定义完整性约束条件的机制,以反映具体应用所涉及的数据必须遵守的特定的语义约束条件。例如,在学校的数据库中规定大学生入学年龄不得超过30岁,硕士研究生入学年龄不得超过38岁,学生累计成绩不得有三门以上不及格等。

  1.2.2 概念模型

  概念模型实际上是现实世界到机器世界的一个中间层次。

  概念模型用于信息世界的建模,是现实世界到信息世界的第一层抽象,是数据库设计人员进行数据库设计的有力工具,也是数据库设计人员和用户之间进行交流的语言,因此概念模型一方面应该具有较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识,另一方面它还应该简单、清晰、易于用户理解。

  一、信息世界中的基本概念

  信息世界涉及的概念主要有:

  (1)实体(Entity

  客观存在并可相互区别的事物称为实体。实体可以是具体的人、事、物,也可以是抽象的概念或联系,例如,一个职工、一个学生、一个部门、一门课、学生的一次选课、部门的一次订货、老师与系的工作关系(即某位老师在某系工作)等都是实体。

  (2)属性(Attribute

  实体所具有的某一特性称为属性。一个实体可以由若干个属性来刻画。例如学生实体可以由学号、姓名、性别、出生年份、系、入学时间等属性组成。(94002268,张山,男,1976,计算机系,1994)这些属性组合起来表征了一个学生。

  (3)码(Key

  唯一标识实体的属性集称为码。例如学号是学生实体的码。

  (4)域(Domain

  属性的取值范围称为该属性的域。例如,学号的域为8位整数,姓名的域为字符串集合,年龄的域为小于38的整数,性别的域为(男,女)。

  (5)实体型(Entity Type

  具有相同属性的实体必然具有共同的特征和性质。用实体名及其属性名集合来抽象和刻画同类实体,称为实体型。例如,学生(学号,姓名,性别,出生年份,系,入学时间)就是一个实体型。

  (6)实体集(Entity Set

  同型实体的集合称为实体集。例如,全体学生就是一个实体集。

  (7)联系(Relationship

  在现实世界中,事物内部以及事物之间是有联系的,这些联系在信息世界中反映为实体(型)内部的联系和实体(型)之间的联系。实体内部的联系通常是指组成实体的各属性之间的联系。实体之间的联系通常是指不同实体集之间的联系。

  两个实体型之间的联系可以分为三类:

  ① 一对一联系(1 : 1

  如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之联系,反之亦然,则称实体集A与实体集B具有一对一联系,记为1 : 1

  例如,学校里面,一个班级只有一个正班长,而一个班长只在一个班中任职,则班级与班长之间具有一对一联系。

  ② 一对多联系(1 : n

  如果对于实体集A中的每一个实体,实体集B中有n个实体(n0)与之联系,反之,对于实体集B中的每一个实体,实体集A中至多只有一个实体与之联系,则称实体集A与实体集B有一对多联系,记为1 : n

  例如,一个班级中有若干名学生,而每个学生只在一个班级中学习,则班级与学生之间具有一对多联系。

  ③ 多对多联系(m : n

  如果对于实体集A中的每一个实体,实体集B中有n个实体(n0)与之联系,反之,对于实体集B中的每一个实体,实体集A中也有m个实体(m0)与之联系,则称实体集A与实体集B具有多对多联系,记为m : n

  二、概念模型的表示方法

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

  这里介绍E-R图的要点。有关如何认识和分析现实世界,从中抽取实体和实体之间的联系,建立概念模型的方法将在第六章讲解。

  E-R图提供了表示实体型、属性和联系的方法:

  · 实体型:用矩形表示,矩形框内写明实体名。

  · 属性:用椭圆形表示,并用无向边将其与相应的实体连接起来。

  · 联系:用菱形表示,菱形框内写明联系名,并用无向边分别与有关实体连接起来,同时在无向边旁标上联系的类型(1 : 11 : nm : n)。

  需要注意的是,如果一个联系具有属性,则这些属性也要用无向边与该联系连接起来。

  实体-联系方法是抽象和描述现实世界的有力工具。用E-R图表示的概念模型独立于具体的DBMS所支持的数据模型,它是各种数据模型的共同基础,因而比数据模型更一般、更抽象、更接近现实世界。

  1.2.3 最常用的数据模型

  目前,数据库领域中最常用的数据模型有四种,它们是:

  · 层次模型 (Hierarchical Model)

  · 网状模型 (Network Model)

  · 关系模型 (Relational Model)

  · 面向对象模型 (Object Oriented Model)

  其中层次模型和网状模型统称为非关系模型。

  非关系模型的数据库系统在20世纪70年代至80年代初非常流行,在数据库系统产品中占据了主导地位,现在已逐渐被关系模型的数据库系统取代,但在美国等一些国家里,由于早期开发的应用系统都是基于层次数据库或网状数据库系统的,因此目前仍有不少层次数据库或网状数据库系统在继续使用。

  20世纪80年代以来,面向对象的方法和技术在计算机各个领域,包括程序设计语言、软件工程、信息系统设计、计算机硬件设计等各方面都产生了深远的影响,也促进数据库中面向对象数据模型的研究和发展。

   本章简要介绍层次模型、网状模型和关系模型。面向对象的数据模型将在第十三章中介绍。

   数据结构、数据操作和完整性约束条件这三个方面的内容完整地描述了一个数据模型,其中数据结构是刻画模型性质的最基本的方面。为了使读者对数据模型有一个基本认识,下面着重介绍三种模型的数据结构。

  注意:这里讲的数据模型都是逻辑上的,也就是说是用户眼中看到的数据范围。同时它们又都是能用某种语言描述,使计算机系统能够理解,被数据库管理系统支持的数据视图。这些数据模型将以一定的方式存储于数据库系统中,这是DBMS的功能,是DBMS中的存储模型。

  在非关系模型中,实体用记录表示,实体的属性对应记录的数据项(或字段)。实体之间的联系在非关系模型中转换成记录之间的两两联系。

  1.2.4 层次模型

  层次模型是数据库系统中最早出现的数据模型,层次数据库系统采用层次模型作为数据的组织方式。层次数据库系统的典型代表是IBM公司的IMSInformation Management System)数据库管理系统,这是1968IBM公司推出的第一个大型的商用数据库管理系统,曾经得到广泛的使用。

  层次模型用树形结构来表示各类实体以及实体间的联系。现实世界中许多实体之间的联系本来就呈现出一种很自然的层次关系,如行政机构、家族关系等。

  一、层次数据模型的数据结构

  在数据库中定义满足下面两个条件的基本层次联系的集合为层次模型。

  (1)有且只有一个结点没有双亲结点,这个结点称为根结点;

  (2)根以外的其他结点有且只有一个双亲结点。

  在层次模型中,每个结点表示一个记录类型,记录(类型)之间的联系用结点之间的连线(有向边)表示,这种联系是父子之间的一对多的联系。这就使得层次数据库系统只能处理一对多的实体联系。

  每个记录类型可包含若干个字段,这里,记录类型描述的是实体,字段描述实体的属性。各个记录类型及其字段都必须命名。各个记录类型、同一记录类型中各个字段不能同名。每个记录类型可以定义一个排序字段,也称为码字段,如果定义该排序字段的值是唯一的,则它能唯一地标识一个记录值。

  一个层次模型在理论上可以包含任意有限个记录型和字段,但任何实际的系统都会因为存储容量或实现复杂度而限制层次模型中包含的记录型个数和字段的个数。

  在层次模型中,同一双亲的子女结点称为兄弟结点(Twin Sibling),没有子女结点的结点称为叶结点。

  二、多对多联系在层次模型中的表示

  前面已经说过,层次数据模型只能直接表示一对多(包括一对一)的联系,那么另一种常见联系-多对多联系能否在层次模型中表示呢?答案是肯定的,否则层次模型就无法真正反映现实世界了。但是用层次模型表示多对多联系,必须首先将其分解成一对多联系。分解方法有两种:冗余结点法和虚拟结点法。下面用一个例子来说明这两种分解方法。

  二、层次模型的数据操纵与完整性约束

  层次模型的数据操纵主要有查询、插入、删除和更新。进行插入、删除、更新操作时要满足层次模型的完整性约束条件。

  进行插入操作时,如果没有相应的双亲结点值就不能插入子女结点值。例如在图1.18的层次数据库中,若新调入一名教师,但尚未分配到某个教研室,这时就不能将新教员插入到数据库中。

  进行删除操作时,如果删除双亲结点值,则相应的子女结点值也被同时删除。例如在图1.18的层次数据库中,若删除网络教研室,则该教研室所有老师的数据将全部丢失。

  进行更新操作时,应更新所有相应记录,以保证数据的一致性。例如在图1.20(b)的层次模型中,如果一个学生要改姓名,则两处学生记录值的姓名字段都需更新。

  三、层次数据模型的存储结构

  层次数据库中不仅要存储数据本身,还要存储数据之间的层次联系。层次模型数据的存储常常是和数据之间联系的存储结合在一起的。

  四、层次模型的优缺点

  层次模型的优点主要有:

  · 层次数据模型本身比较简单。

  · 对于实体间联系是固定的,且预先定义好的应用系统,采用层次模型来实现,其性能优于关系模型,不低于网状模型。

  · 层次数据模型提供了良好的完整性支持。

  层次模型的缺点主要有:

  · 现实世界中很多联系是非层次性的,如多对多联系、一个结点具有多个双亲等,层次模型表示这类联系的方法很笨拙,只能通过引入冗余数据(易产生不一致性)或创建非自然的数据组织(引入虚拟结点)来解决。

  · 对插入和删除操作的限制比较多。

  · 查询子女结点必须通过双亲结点。

  · 由于结构严密,层次命令趋于程序化。

  可见用层次模型对具有一对多的层次关系的部门描述非常自然、直观,容易理解。这是层次数据库的突出优点。

  1.2.5 网状模型

  在现实世界中事物之间的联系更多的是非层次关系的,用层次模型表示非树形结构是很不直接的,网状模型则可以克服这一弊病。

  网状数据库系统采用网状模型作为数据的组织方式。网状数据模型的典型代表是DBTG系统,亦称CODASYL系统。这是70年代数据系统语言研究会CODASYLConference On Data System Language)下属的数据库任务组(Data Base Task Group,简称DBTG)提出的一个系统方案。DBTG系统虽然不是实际的软件系统,但是它提出的基本概念、方法和技术具有普遍意义。它对于网状数据库系统的研制和发展起了重大的影响。后来不少的系统都采用DBTG模型或者简化的DBTG模型。例如,Cullinet Software公司的 IDMSUnivac公司的DMS1100Honeywell公司的IDS/2HP公司的IMAGE等。

  一、网状数据模型的数据结构

  在数据库中,把满足以下两个条件的基本层次联系集合称为网状模型:

  (1)允许一个以上的结点无双亲;

  (2)一个结点可以有多于一个的双亲。

  网状模型是一种比层次模型更具普遍性的结构,它去掉了层次模型的两个限制,允许多个结点没有双亲结点,允许结点有多个双亲结点,此外它还允许两个结点之间有多种联系(称之为复合联系)。因此网状模型可以更直接地去描述现实世界。而层次模型实际上是网状模型的一个特例。

  与层次模型一样,网状模型中每个结点表示一个记录类型(实体),每个记录类型可包含若干个字段(实体的属性),结点间的连线表示记录类型(实体)之间一对多的父子联系。

  二、网状数据模型的操纵与完整性约束

  网状数据模型一般来说没有层次模型那样严格的完整性约束条件,但具体的网状数据库系统(如DBTG)对数据操纵都加了一些限制,提供了一定的完整性约束。

  DBTG在模式DDL中提供了定义DBTG数据库完整性的若干概念和语句,主要有:

  (1)支持记录码的概念,码即唯一标识记录的数据项的集合。例如,学生记录(如图1.25)中学号是码,因此数据库中不允许学生记录中学号出现重复值。

   2)保证一个联系中双亲记录和子女记录之间是一对多的联系。

  (3)可以支持双亲记录和子女记录之间某些约束条件。例如,有些子女记录要求双亲记录存在才能插入,双亲记录删除时也连同删除。例如图1.26SC记录就应该满足这种约束条件,学生选课记录值必须是数据库中存在的某一学生,某一门课的选修记录。DBTG提供了"属籍类别"的概念来描述这类约束条件。

  三、网状数据模型的存储结构

  网状数据模型的存储结构中关键是如何实现记录之间的联系。常用的方法是链接法,包括单向链接、双向链接、环状链接、向首链接等,此外还有其他实现方法,如指引元阵列法、二进制阵列法、索引法等依具体系统不同而不同。

  四、网状数据模型的优缺点

  网状数据模型的优点主要有:

  · 能够更为直接地描述现实世界,如一个结点可以有多个双亲。

  · 具有良好的性能,存取效率较高。

  网状数据模型的缺点主要有:

  · 结构比较复杂,而且随着应用环境的扩大,数据库的结构就变得越来越复杂,不利于最终用户掌握。

  · DDLDML语言复杂,用户不容易使用。

  由于记录之间联系是通过存取路径实现的,应用程序在访问数据时必须选择适当的存取路径,因此,用户必须了解系统结构的细节,加重了编写应用程序的负担。

  1.2.6 关系模型

  关系模型是目前最重要的一种数据模型。关系数据库系统采用关系模型作为数据的组织方式。

  1970年美国IBM公司San Jose研究室的研究员E.F.Codd首次提出了数据库系统的关系模型,开创了数据库关系方法和关系数据理论的研究,为数据库技术奠定了理论基础。由于E.F.Codd的杰出工作,他于1981年获得ACM图灵奖。

  20世纪80年代以来,计算机厂商新推出的数据库管理系统几乎都支持关系模型,非关系系统的产品也大都加上了关系接口。数据库领域当前的研究工作也都是以关系方法为基础。因此本书的重点也将放在关系数据库上,下面四章将详细讲解关系数据库。

  一、关系数据模型的数据结构

  关系模型与以往的模型不同,它是建立在严格的数学概念的基础上的。严格的定义将在下一章给出。这里只简单勾画一下关系模型。在用户观点下,关系模型中数据的逻辑结构是一张二维表,它由行和列组成。

  · 关系(Relation):一个关系对应通常说的一张表,如图1.27中的这张学生登记表;

  · 元组(Tuple):表中的一行即为一个元组;

  · 属性(Attribute):表中的一列即为一个属性,给每一个属性起一个名称即属性名。如上表有六列,对应六个属性(学号,姓名,年龄,性别,系和年级);

  · 主码(Key):表中的某个属性组,它可以唯一确定一个元组,如图1.27中的学号,可以唯一确定一个学生,也就成为本关系的主码;

  · 域(Domain):属性的取值范围,如人的年龄一般在1150岁之间,大学生年龄属性的域是(1438),性别的域是(男,女),系别的域是一个学校所有系名的集合;

  · 分量:元组中的一个属性值;

  · 关系模式:对关系的描述,一般表示为:

   关系名(属性1,属性2,…,属性n

  例如上面的关系可描述为:

   学生(学号,姓名,年龄,性别,系和年级)

  在关系模型中,实体以及实体间的联系都是用关系来表示。例如学生、课程、学生与课程之间的多对多联系在关系模型中可以如下表示:

   学生(学号,姓名,年龄,性别,系和年级)

   课程(课程号,课程名,学分)

    选修(学号,课程号,成绩)

  关系模型要求关系必须是规范化的,即要求关系必须满足一定的规范条件,这些规范条件中最基本的一条就是,关系的每一个分量必须是一个不可分的数据项,也就是说,不允许表中还有表。

  二、关系数据模型的操纵与完整性约束

  关系数据模型的操作主要包括查询、插入、删除和更新数据。这些操作必须满足关系的完整性约束条件。关系的完整性约束条件包括三大类:实体完整性、参照完整性和用户定义的完整性。其具体含义将在后面介绍。

  关系模型中的数据操作是集合操作,操作对象和操作结果都是关系,即若干元组的集合,而不像非关系模型中那样是单记录的操作方式。另一方面,关系模型把存取路径向用户隐蔽起来,用户只要指出"干什么"或"找什么",不必详细说明"怎么干"或"怎么找",从而大大地提高了数据的独立性,提高了用户生产率。

  三、关系数据模型的存储结构

  在关系数据模型中,实体及实体间的联系都用表来表示。在数据库的物理组织中,表以文件形式存储,有的系统一个表对应一个操作系统文件,有的系统自己设计文件结构。

  四、关系数据模型的优缺点

  关系数据模型具有下列优点:

  · 关系模型与非关系模型不同,它是建立在严格的数学概念的基础上的。

  · 关系模型的概念单一。无论实体还是实体之间的联系都用关系表示。对数据的检索结果也是关系(即表)。所以其数据结构简单、清晰,用户易懂易用。

  · 关系模型的存取路径对用户透明,从而具有更高的数据独立性、更好的安全保密性,也简化了程序员的工作和数据库开发建立的工作。

  

  所以关系数据模型诞生以后发展迅速,深受用户的喜爱。

  当然,关系数据模型也有缺点,其中最主要的缺点是,由于存取路径对用户透明,查询效率往往不如非关系数据模型。因此为了提高性能,必须对用户的查询请求进行优化,增加了开发数据库管理系统的难度。

第一章 绪论

 

第三节 数据库系统结构

 

  考察数据库系统的结构可以有多种不同的层次或不同的角度。

  从数据库管理系统角度看,数据库系统通常采用三级模式结构;这是数据库管理系统内部的系统结构。

  从数据库最终用户角度看,数据库系统的结构分为单用户结构、主从式结构、分布式结构和客户/服务器结构。这是数据库系统外部的体系结构。

  本章介绍数据库系统的模式结构。有关数据库系统的单用户结构、主从式结构、分布式结构和客户/服务器结构放在后面第十二章中介绍。

  1.3.1 数据库系统模式的概念

  在数据模型中有"型"(Type)和"值"(Value)的概念。型是指对某一类数据的结构和属性的说明,值是型的一个具体赋值。例如:学生记录定义为(学号,姓名,性别,系别,年龄,籍贯)这样的记录型,而(900201,李明,男,计算机,22,江苏)则是该记录型的一个记录值。

  模式(Schema)是数据库中全体数据的逻辑结构和特征的描述,它仅仅涉及到型的描述,不涉及到具体的值。模式的一个具体值称为模式的一个实例(Instance)。同一个模式可以有很多实例。模式是相对稳定的,而实例是相对变动的,因为数据库中的数据是在不断更新的。模式反映的是数据的结构及其联系,而实例反映的是数据库某一时刻的状态。

  虽然实际的数据库管理系统产品种类很多,它们支持不同的数据模型,使用不同的数据库语言,建立在不同的操作系统之上,数据的存储结构也各不相同,但它们在体系结构上通常都具有相同的特征,即采用三级模式结构(早期微机上的小型数据库系统除外)并提供两级映象功能。

  1.3.2 数据库系统的三级模式结构

  数据库系统的三级模式结构是指数据库系统是由外模式、模式和内模式三级构成。

  一、模式(Schema

  模式也称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。它是数据库系统模式结构的中间层,既不涉及数据的物理存储细节和硬件环境,也与具体的应用程序,与所使用的应用开发工具及高级程序设计语言(如CCOBOLFORTRAN)无关。

  模式实际上是数据库数据在逻辑级上的视图。一个数据库只有一个模式。数据库模式以某一种数据模型为基础,统一综合地考虑了所有用户的需求,并将这些需求有机地结合成一个逻辑整体。定义模式时不仅要定义数据的逻辑结构,例如数据记录由哪些数据项构成,数据项的名字、类型、取值范围等,而且要定义数据之间的联系,定义与数据有关的安全性、完整性要求。

  DBSM提供模式描述语言(模式DDL)来严格地定义模式。

  二、外模式(External Schema

  外模式也称子模式(Subschema)或用户模式,它是数据库用户(包括应用程序员和最终用户)能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。

  外模式通常是模式的子集。一个数据库可以有多个外模式。由于它是各个用户的数据视图,如果不同的用户在应用需求、看待数据的方式、对数据保密的要求等方面存在差异,则其外模式描述就是不同的。即使对模式中同一数据,在外模式中的结构、类型、长度、保密级别等都可以不同。另一方面,同一外模式也可以为某一用户的多个应用系统所使用,但一个应用程序只能使用一个外模式。

  外模式是保证数据库安全性的一个有力措施。每个用户只能看见和访问所对应的外模式中的数据,数据库中的其余数据是不可见的。

  DBSM提供子模式描述语言(子模式DDL)来严格地定义子模式。

  三、内模式(Internal Schema

  内模式也称存储模式(Storage Schema),一个数据库只有一个内模式。它是数据物理结构和存储方式的描述,是数据在数据库内部的表示方式。例如,记录的存储方式是顺序存储、按照B树结构存储还是按hash方法存储;索引按照什么方式组织;数据是否压缩存储,是否加密;数据的存储记录结构有何规定等。

  DBSM提供内模式描述语言(内模式DDL,或者存储模式DDL)来严格地定义内模式。

  1.3.3 数据库的二级映象功能与数据独立性

  数据库系统的三级模式是对数据的三个抽象级别,它把数据的具体组织留给DBMS管理,使用户能逻辑地抽象地处理数据,而不必关心数据在计算机中的具体表示方式与存储方式。为了能够在内部实现这三个抽象层次的联系和转换,数据库管理系统在这三级模式之间提供了两层映象:

  · 外模式/模式映象

  · 模式/内模式映象

  正是这两层映象保证了数据库系统中的数据能够具有较高的逻辑独立性和物理独立性。

  一、外模式/模式映象

  模式描述的是数据的全局逻辑结构,外模式描述的是数据的局部逻辑结构。对应于同一个模式可以有任意多个外模式。对于每一个外模式,数据库系统都有一个外模式/模式映象,它定义了该外模式与模式之间的对应关系。这些映象定义通常包含在各自外模式的描述中。

  

  当模式改变时(例如增加新的关系、新的属性、改变属性的数据类型等),由数据库管理员对各个外模式/模式的映象作相应改变,可以使外模式保持不变。应用程序是依据数据的外模式编写的,从而应用程序不必修改,保证了数据与程序的逻辑独立性,简称数据的逻辑独立性。

  二、模式/内模式映象

  数据库中只有一个模式,也只有一个内模式,所以模式/内模式映象是唯一的,它定义了数据全局逻辑结构与存储结构之间的对应关系。例如,说明逻辑记录和字段在内部是如何表示的。该映象定义通常包含在模式描述中。当数据库的存储结构改变了(例如选用了另一种存储结构),由数据库管理员对模式/内模式映象作相应改变,可以使模式保持不变,从而应用程序也不必改变。保证了数据与程序的物理独立性,简称数据的物理独立性。

  在数据库的三级模式结构中,数据库模式即全局逻辑结构是数据库的中心与关键,它独立于数据库的其他层次。因此设计数据库模式结构时应首先确定数据库的逻辑模式。

  数据库的内模式依赖于它的全局逻辑结构,但独立于数据库的用户视图即外模式,也独立于具体的存储设备。它是将全局逻辑结构中所定义的数据结构及其联系按照一定的物理存储策略进行组织,以达到较好的时间与空间效率。

  数据库的外模式面向具体的应用程序,它定义在逻辑模式之上,但独立于存储模式和存储设备。当应用需求发生较大变化,相应外模式不能满足其视图要求时,该外模式就得做相应改动,所以设计外模式时应充分考虑到应用的扩充性。

  特定的应用程序是在外模式描述的数据结构上编制的,它依赖于特定的外模式,与数据库的模式和存储结构独立。不同的应用程序有时可以共用同一个外模式。数据库的二级映象保证了数据库外模式的稳定性,从而从底层保证了应用程序的稳定性,除非应用需求本身发生变化,否则应用程序一般不需要修改。

  数据与程序之间的独立性,使得数据的定义和描述可以从应用程序中分离出去。另外,由于数据的存取由DBMS管理,用户不必考虑存取路径等细节,从而简化了应用程序的编制,大大减少了应用程序的维护和修改。

第一章 绪论

 

第四节 数据库系统的组成

 

  在本章一开始介绍了数据库系统一般由数据库、数据库管理系统(及其开发工具)、应用系统、数据库管理员和用户构成。下面分别介绍这几个部分的内容。

  一、硬件平台及数据库

  由于数据库系统数据量都很大,加之DBMS丰富的功能使得自身的规模也很大,因此整个数据库系统对硬件资源提出了较高的要求,这些要求是:

  (1)要有足够大的内存,存放操作系统、DBMS的核心模块、数据缓冲区和应用程序。

  (2)有足够的大的磁盘等直接存取设备存放数据库,有足够的磁带(或微机软盘)作数据备份。

  (3)要求系统有较高的通道能力,以提高数据传送率。

  二、软件

  数据库系统的软件主要包括:

  (1DBMSDBMS是为数据库的建立、使用和维护配置的软件。

  (2)支持DBMS运行的操作系统。

  (3)具有与数据库接口的高级语言及其编译系统,便于开发应用程序。

  (4 DBMS为核心的应用开发工具。

  应用开发工具是系统为应用开发人员和最终用户提供的高效率、多功能的应用生成器、第四代语言等各种软件工具。它们为数据库系统的开发和应用提供了良好的环境。

  (5 为特定应用环境开发的数据库应用系统。

  三、人员

  开发、管理和使用数据库系统的人员主要是:数据库管理员、系统分析员和数据库设计人员、应用程序员和最终用户。不同的人员涉及不同的数据抽象级别,具有不同的数据视图。

  1. 数据库管理员(DataBase Administrator,简称DBA)

  在数据库系统环境下,有两类共享资源。一类是数据库,另一类是数据库管理系统软件。因此需要有专门的管理机构来监督和管理数据库系统。DBA则是这个机构的一个(组)人员,负责全面管理和控制数据库系统。具体职责包括:

  (1)决定数据库中的信息内容和结构

  数据库中要存放哪些信息,DBA要参与决策。因此DBA必须参加数据库设计的全过程,并与用户、应用程序员、系统分析员密切合作共同协商,搞好数据库设计。

  (2)决定数据库的存储结构和存取策略

  DBA要综合各用户的应用要求,和数据库设计人员共同决定数据的存储结构和存取策略以求获得较高的存取效率和存储空间利用率。

  (3)定义数据的安全性要求和完整性约束条件

  DBA的重要职责是保证数据库的安全性和完整性。因此DBA负责确定各个用户对数据库的存取权限、数据的保密级别和完整性约束条件。

  (4)监控数据库的使用和运行

  DBA还有一个重要职责就是监视数据库系统的运行情况,及时处理运行过程中出现的问题。比如系统发生各种故障时,数据库会因此遭到不同程度的破坏,DBA必须在最短时间内将数据库恢复到正确状态,并尽可能不影响或少影响计算机系统其他部分的正常运行。为此,DBA要定义和实施适当的后备和恢复策略。如周期性的转储数据、维护日志文件等等。有关这方面的内容将在下面做进一步讨论。

  (5)数据库的改进和重组重构

  DBA还负责在系统运行期间监视系统的空间利用率、处理效率等性能指标,对运行情况进行记录、统计分析,依靠工作实践并根据实际应用环境,不断改进数据库设计。不少数据库产品都提供了对数据库运行状况进行监视和分析的实用程序,DBA可以使用这些实用程序完成这项工作。

  另外,在数据运行过程中,大量数据不断插入、删除、修改,时间一长,会影响系统的性能。因此,DBA要定期对数据库进行重组织,以提高系统的性能。

  

  当用户的需求增加和改变时,DBA还要对数据库进行较大的改造,包括修改部分设计,即数据库的重构造。

  2. 系统分析员和数据库设计人员

  系统分析员负责应用系统的需求分析和规范说明,要和用户及DBA相结合,确定系统的硬件软件配置,并参与数据库系统的概要设计。

  数据库设计人员负责数据库中数据的确定、数据库各级模式的设计。数据库设计人员必须参加用户需求调查和系统分析,然后进行数据库设计。在很多情况下,数据库设计人员就由数据库管理员担任。

  3. 应用程序员

  应用程序员负责设计和编写应用系统的程序模块,并进行调试和安装。

  4. 用户

  这里用户是指最终用户(End User)。最终用户通过应用系统的用户接口使用数据库。常用的接口方式有浏览器、菜单驱动、表格操作、图形显示、报表书写等。

  最终用户可以分为如下三类:

  (1)偶然用户。这类用户不经常访问数据库,但每次访问数据库时往往需要不同的数据库信息,这类用户一般是企业或组织机构的高中级管理人员。

  (2)简单用户。数据库的多数最终用户都是简单用户。其主要工作是查询和更新数据库,一般都是通过应用程序员精心设计并具有友好界面的应用程序存取数据库。银行的职员、航空公司的机票预定工作人员、旅馆总台服务员等都属于这类用户。

  (3)复杂用户。复杂用户包括工程师、科学家、经济学家、科学技术工作者等具有较高科学技术背景的人员。这类用户一般都比较熟悉数据库管理系统的各种功能,能够直接使用数据库语言访问数据库,甚至能够基于数据库管理系统的API编制自己的应用程序。

第一章 绪论

 

第五节 数据库技术的研究领域

 

  数据库学科的研究范围是十分广泛的,概括地讲可包括以下三个领域:

  一、数据库管理系统软件的研制

  DBMS是数据库系统的基础。DBMS的研制包括研制DBMS本身及以DBMS为核心的一组相互联系的软件系统,包括工具软件和中间件。研制的目标是提高系统的可用性、可靠性、可伸缩性;提高性能和提高用户的生产率。

  DBMS核心技术的研究和实现是三十余年来数据库领域所取得的主要成就。DBMS是一个基础软件系统,它提供了对数据库中的数据进行存储、检索和管理的功能。

  二、数据库设计

  数据库设计的主要任务是在DBMS的支持下,按照应用的要求,为某一部门或组织设计一个结构合理、使用方便、效率较高的数据库及其应用系统。其中主要的研究方向是数据库设计方法学和设计工具,包括数据库设计方法、设计工具和设计理论的研究,数据模型和数据建模的研究,计算机辅助数据库设计方法及其软件系统的研究,数据库设计规范和标准的研究等。

  三、数据库理论

  数据库理论的研究主要集中于关系的规范化理论、关系数据理论等。近年来,随着人工智能与数据库理论的结合、并行计算技术等的发展,数据库逻辑演绎和知识推理、数据库中的知识发现(Knowledge Discovery from Database,简称KDD)、并行算法等成为新的理论研究方向。

  计算机领域中其他新兴技术的发展对数据库技术产生了重大影响。数据库技术和其他计算机技术的互相结合、互相渗透,使数据库中新的技术内容层出不穷。数据库的许多概念、技术内容、应用领域,甚至某些原理都有了重大的发展和变化。建立和实现了一系列新型数据库系统,如分布式数据库系统、并行数据库系统、知识库系统、多媒体数据库系统等。它们共同构成了数据库系统大家族,使数据库技术不断地涌现新的研究方向。

  本书介绍数据库系统的基本概念、基本技术和基本知识方面是进一步进行上述三个领域研究和开发的基础。

第一章 绪论

 

第六节 小结

 

  本章概述了数据库的基本概念,并通过对数据管理进展情况的介绍,阐述了数据库技术产生和发展的背景,也说明了数据库系统的优点。

  数据模型是数据库系统的核心和基础。本章介绍了组成数据模型的三个要素、概念模型和三种主要的数据库模型。

  概念模型也称信息模型,用于信息世界的建模,E-R模型是这类模型的典型代表,E-R方法简单、清晰,应用十分广泛。

  

  数据模型的发展经历了格式化数据模型(包括层次模型和网状模型)、关系模型,正在走向面向对象等非传统数据模型。由于层次数据库和网状数据库已逐渐被关系数据库代替,本书不再用单独的章节讲解,因此本章较为详细地讲解了层次模型和网状模型,而关系模型只是简单介绍,后面会详细讲解。

  数据库系统三级模式和两层映象的系统结构保证了数据库系统中能够具有较高的逻辑独立性和物理独立性。

  最后介绍了数据库系统的组成,使读者了解数据库系统不仅是一个计算机系统,而是一个人-机系统,人的作用特别是DBA的作用尤为重要。

  学习这一章应把注意力放在掌握基本概念和基本知识方面,为进一步学习下面章节打好基础。本章新概念较多,如果是刚开始学习数据库,可在学习后面章节后再回来理解和掌握这些概念。

第二章 关系数据库

 

第一节 关系模型概述

 

  关系数据库系统是支持关系模型的数据库系统。

  关系模型由关系数据结构、关系操作集合和关系完整性约束三部分组成。

  一、单一的数据结构——关系

  关系模型的数据结构非常单一。在关系模型中,现实世界的实体以及实体间的各种联系均用关系来表示。在用户看来,关系模型中数据的逻辑结构是一张二维表。

  二、关系操作

  关系模型给出了关系操作的能力,但不对RDBMS语言给出具体的语法要求。

  关系模型中常用的关系操作包括:选择(Select)、投影(Project)、连接(Join)、除(Divide)、并(Union)、交(Intersection)、差(Difference)等查询(Query)操作和增加(Insert)、删除(Delete)、修改(Update)操作两大部分。查询的表达能力是其中最主要的部分。

  关系操作的特点是集合操作方式,即操作的对象和结果都是集合。这种操作方式也称为一次一集合(set-at-a-time)的方式。相应地,非关系数据模型的数据操作方式则为一次一记录(record-at-a-time)的方式。

  早期的关系操作能力通常用代数方式或逻辑方式来表示,分别称为关系代数和关系演算。关系代数是用对关系的运算来表达查询要求的方式。关系演算是用谓词来表达查询要求的方式。关系演算又可按谓词变元的基本对象是元组变量还是域变量分为元组关系演算和域关系演算。关系代数、元组关系演算和域关系演算三种语言在表达能力上是完全等价的。

  关系代数、元组关系演算和域关系演算均是抽象的查询语言,这些抽象的语言与具体的DBMS中实现的实际语言并不完全一样。但它们能用作评估实际系统中查询语言能力的标准或基础。实际的查询语言除了提供关系代数或关系演算的功能外,还提供了许多附加功能,例如集函数、关系赋值、算术运算等。

  关系语言是一种高度非过程化的语言,用户不必请求DBA为其建立特殊的存取路径,存取路径的选择由DBMS的优化机制来完成,此外,用户不必求助于循环结构就可以完成数据操作。

  另外还有一种介于关系代数和关系演算之间的语言SQLStandard Query Language)。SQL不仅具有丰富的查询功能,而且具有数据定义和数据控制功能,是集查询、DDLDMLDCL于一体的关系数据语言。它充分体现了关系数据语言的特点和优点,是关系数据库的标准语言。

  因此,关系数据语言可以分为三类:

  关系代数语言,例如ISBL

  关系演算语言,(元组关系演算语言 ,例如APLHAQUEL 域关系演算语言,例如QBE

  具有关系代数和关系演算双重特点的语言 例如SQL

  这些关系数据语言的共同特点是,语言具有完备的表达能力,是非过程化的集合操作语言,功能强,能够嵌入高级语言中使用。

  三、关系的三类完整性约束

  关系模型允许定义三类完整性约束:实体完整性、参照完整性和用户定义的完整性。其中实体完整性和参照完整性是关系模型必须满足的完整性约束条件,应该由关系系统自动支持。用户定义的完整性是应用领域需要遵循的约束条件,体现了具体领域中的语义约束。

  下面将分别介绍关系模型的三个方面。其中2.2节介绍关系数据结构,包括关系的形式化定义及有关概念;2.3节介绍关系的三类完整性;2.4节介绍关系代数;2.5节介绍关系演算;第三章将专门介绍SQL语言。

第二章 关系数据库

 

第二节 关系数据结构及形式化定义

 

  在关系模型中,无论是实体还是实体之间的联系均由单一的结构类型即关系(表)来表示。前面已经非形式化地介绍了关系模型及有关的基本概念。关系模型是建立在集合代数的基础上的,这里从集合论角度给出关系数据结构的形式化定义。

  2.2.1 关系

  1. 域(Domain

  定义2.1 域是一组具有相同数据类型的值的集合。

  例如,自然数、整数、实数、长度小于25字节的字符串集合、{01}、大于等于0且小于等于100的正整数等,都可以是域。

  2. 笛卡尔积(Cartesian Product

  定义2.2 给定一组域D1D2,…,Dn,这些域中可以有相同的。D1D2,…,Dn的笛卡尔积为:

  D1×D2×…×Dn={(d1d2,…,dn)|di?Dii12,…,n

  其中每一个元素(d1d2,…,dn)叫作一个n元组(n-tuple)或简称元组(Tuple)。

  元素中的每一个值di叫作一个分量(Component)。

  笛卡尔积可表示为一个二维表。表中的每行对应一个元组,表中的每列对应一个域。例如给出三个域:

   D1=导师集合SUPERVISOR=张清玫,刘逸

   D2=专业集合SPECIALITY=计算机专业,信息专业

   D3=研究生集合POSTGRADUATE=李勇,刘晨,王敏

  则D1D2D3的笛卡尔积为:

  D1×D2×D3 ={(张清玫,计算机专业,李勇)(张清玫,计算机专业,刘晨)

   (张清玫,计算机专业,王敏)(张清玫,信息专业,李勇)

   (张清玫,信息专业,刘晨)(张清玫,信息专业,王敏)

   (刘逸,计算机专业,李勇)(刘逸,计算机专业,刘晨)

   (刘逸,计算机专业,王敏)(刘逸,信息专业,李勇)

   (刘逸,信息专业,刘晨)(刘逸,信息专业,王敏)

  其中(张清玫,计算机专业,李勇)(张清玫,计算机专业,刘晨)等都是元组。张清玫、计算机专业、李勇、刘晨等都是分量。

  该笛卡尔积的基数为2×2×312,也就是说,D1×D2×D3一共有2×2×312个元组。这12个元组可列成一张二维表(如表2.1)。

  3. 关系(Relation

  定义2.3 D1×D2×…×Dn的子集叫作在域D1D2,…,Dn上的关系,表示为

   RD1D2,…,Dn

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

  关系中的每个元素是关系中的元组,通常用t表示。

  当n=1时,称该关系为单元关系(Unary relation)。

  当n=2时,称该关系为二元关系(Binary relation)。

  关系是笛卡尔积的有限子集,所以关系也是一个二维表,表的每行对应一个元组,表的每列对应一个域。由于域可以相同,为了加以区分,必须对每列起一个名字,称为属性(Attribute)。n目关系必有n个属性。

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

  若一个关系有多个候选码,则选定其中一个为主码(Primary key)。主码的诸属性称为主属性(Prime attribute)。不包含在任何侯选码中的属性称为非码属性(Non-key attribute)。 在最简单的情况下,候选码只包含一个属性。在最极端的情况下,关系模式的所有属性组是这个关系模式的候选码,称为全码(All-key)。

  关系可以有三种类型:基本关系(通常又称为基本表或基表)、查询表和视图表。基本表是实际存在的表,它是实际存储数据的逻辑表示。查询表是查询结果对应的表。视图表是由基本表或其他视图表导出的表,是虚表,不对应实际存储的数据。

  按照定义2.2,关系可以是一个无限集合。由于笛卡尔积不满足交换律,所以按照数学定义,(d1d2,…,dn )(d2d1,…,dn )。当关系作为关系数据模型的数据结构时,需要给予如下的限定和扩充:

  (1)无限关系在数据库系统中是无意义的。因此,限定关系数据模型中的关系必须是有限集合。

  (2)通过为关系的每个列附加一个属性名的方法取消关系元组的有序性,即(d1d2 ,…,di dj ,…,dn=d1d2 ,…,didj ,…,dn ij = 12,…,n)。

  因此,基本关系具有以下六条性质:

  ① 列是同质的(Homogeneous),即每一列中的分量是同一类型的数据,来自同一个域。

  ② 不同的列可出自同一个域,称其中的每一列为一个属性,不同的属性要给予不同的属性名。

  例如在上面的例子中,也可以只给出两个域:

  人(PERSON=张清玫,刘逸,李勇,刘晨,王敏

  专业(SPECIALITY=计算机专业,信息专业

  SAP关系的导师属性和研究生属性都从PERSON域中取值。为了避免混淆,必须给这两个属性取不同的属性名,而不能直接使用域名。例如定义导师属性名为SUPERVISOR-PERSON(或SUPERVISOR),研究生属性名为POSTGRADUATE-PERSON(或POSTGRADUATE)。

  ③ 列的顺序无所谓,即列的次序可以任意交换。

  由于列顺序是无关紧要的,因此在许多实际关系数据库产品中(例如Oracle),增加新属性时,永远是插至最后一列。

  ④ 任意两个元组不能完全相同。

  ⑤ 行的顺序无所谓,即行的次序可以任意交换。

  ⑥ 分量必须取原子值,即每一个分量都必须是不可分的数据项。

  注意:在许多实际关系数据库产品中,基本表并不完全具有这六条性质,例如,有的数据库产品(如FoxPro)仍然区分了属性顺序和元组的顺序;许多关系数据库产品中,例如OracleFoxPro等,它们都允许关系表中存在两个完全相同的元组,除非用户特别定义了相应的约束条件。

  关系模型要求关系必须是规范化的,即要求关系模式必须满足一定的规范条件。这些规范条件中最基本的一条就是,关系的每一个分量必须是一个不可分的数据项。规范化的关系简称为范式(Normal Form)。

  2.2.2 关系模式

  在数据库中要区分型和值。关系数据库中,关系模式是型,关系是值。关系模式是对关系的描述,那么一个关系需要描述哪些方面呢?

  首先,应该知道,关系实质上是一张二维表,表的每一行为一个元组,每一列为一个属性。一个元组就是该关系所涉及的属性集的笛卡尔积的一个元素。关系是元组的集合,因此关系模式必须指出这个元组集合的结构,即它由哪些属性构成,这些属性来自哪些域,以及属性与域之间的映象关系。

  其次,一个关系通常是由赋予它的元组语义来确定的。元组语义实质上是一个n目谓词(n是属性集中属性的个数)。凡使该n目谓词为真的笛卡尔积中的元素(或者说凡符合元组语义的那部分元素)的全体就构成了该关系模式的关系。

  现实世界随着时间在不断地变化,因而在不同的时刻,关系模式的关系也会有所变化。但是,现实世界的许多已有事实限定了关系模式所有可能的关系必须满足一定的完整性约束条件。这些约束或者通过对属性取值范围的限定,例如职工年龄小于65岁(65岁以后必须退休),或者通过属性值间的相互关连(主要体现于值的相等与否)反映出来。关系模式应当刻划出这些完整性约束条件。

  因此一个关系模式应当是一个5元组。

  定义2.4 关系的描述称为关系模式(Relation Schema)。它可以形式化地表示为:

   RUDdomF

  其中R为关系名,U为组成该关系的属性名集合,D为属性组U中属性所来自的域,dom为属性向域的映象集合,F为属性间数据的依赖关系集合。

  属性间的数据依赖将在第五章讨论,本章中关系模式仅涉及关系名、各属性名、域名、属性向域的映像四部分。

  例如,在上面例子中,由于导师和研究生出自同一个域——人,所以要取不同的属性名,并在模式中定义属性向域的映象,即说明它们分别出自哪个域,如:

  domSUPERVISOR-PERSON= domPOSTGRADUATE-PERSON=PERSON

  关系模式通常可以简记为

   R (U)

  或 R (A1A2,…,An)

  其中R为关系名,A1A2,…,An为属性名。而域名及属性向域的映象常常直接说明为属性的类型、长度。

  关系是关系模式在某一时刻的状态或内容。关系模式是静态的、稳定的,而关系是动态的、随时间不断变化的,因为关系操作在不断地更新着数据库中的数据。但在实际当中,人们常常把关系模式和关系都称为关系,这不难从上下文中加以区别。

  2.2.3 关系数据库

  在关系模型中,实体以及实体间的联系都是用关系来表示的。例如导师实体、研究生实体、导师与研究生之间的一对多联系都可以分别用一个关系来表示。在一个给定的应用领域中,所有实体及实体之间联系的关系的集合构成一个关系数据库。

  

  关系数据库也有型和值之分。关系数据库的型也称为关系数据库模式,是对关系数据库的描述,它包括若干域的定义以及在这些域上定义的若干关系模式。关系数据库的值是这些关系模式在某一时刻对应的关系的集合,通常就称为关系数据库。

第二章 关系数据库

 

第三节 关系的完整性

 

  关系模型的完整性规则是对关系的某种约束条件。关系模型中可以有三类完整性约束:实体完整性、参照完整性和用户定义的完整性。其中实体完整性和参照完整性是关系模型必须满足的完整性约束条件,被称作是关系的两个不变性,应该由关系系统自动支持。

  一、实体完整性(Entity Integrity

  规则2.1 实体完整性规则 若属性A是基本关系R的主属性,则属性A不能取空值。

  例如在关系"SAP(SUPERVISORSPECIALITYPOSTGRADUATE)"中,"研究生姓名POSTGRADUATE"属性为主码(假设研究生不会重名),则"研究生姓名"不能取空值。

  实体完整性规则规定基本关系的所有主属性都不能取空值,而不仅是主码整体不能取空值。例如学生选课关系"选修(学号,课程号,成绩)"中,"学号、课程号"为主码,则"学号"和"课程号"两个属性都不能取空值。

  对于实体完整性规则说明如下:

  (1)实体完整性规则是针对基本关系而言的。一个基本表通常对应现实世界的一个实体集。例如学生关系对应于学生的集合。

  (2)现实世界中的实体是可区分的,即它们具有某种唯一性标识。

  (3)相应地,关系模型中以主码作为唯一性标识。

  (4)主码中的属性即主属性不能取空值。所谓空值就是"不知道"或"无意义"的值。如果主属性取空值,就说明存在某个不可标识的实体,即存在不可区分的实体,这与第(2)点相矛盾,因此这个规则称为实体完整性。

  二、参照完整性(Referential Integrity

  现实世界中的实体之间往往存在某种联系,在关系模型中实体及实体间的联系都是用关系来描述的。这样就自然存在着关系与关系间的引用。

  参照完整性规则就是定义外码与主码之间的引用规则。

  规则2.2 参照完整性规则 若属性(或属性组)F是基本关系R的外码,它与基本关系S的主码Ks相对应(基本关系RS不一定是不同的关系),则对于R中每个元组在F上的值必须为:

  · 或者取空值(F的每个属性值均为空值);

  · 或者等于S中某个元组的主码值。

  例如,对于[1],学生关系中每个元组的"专业号"属性只能取下面两类值:

  (1)空值,表示尚未给该学生分配专业;

  (2)非空值,这时该值必须是专业关系中某个元组的"专业号"值,表示该学生不可能分配到一个不存在的专业中。即被参照关系"专业"中一定存在一个元组,它的主码值等于该参照关系"学生"中的外码值。

  对于[2],按照参照完整性规则,"学号"和"课程号"属性也可以取两类值:空值或目标关系中已经存在的值。但由于"学号"和"课程号"是选修关系中的主属性,按照实体完整性规则,它们均不能取空值。所以选修关系中的"学号"和"课程号"属性实际上只能取相应被参照关系中已经存在的主码值。

  参照完整性规则中,RS可以是同一个关系。例如对于[3],按照参照完整性规则,"班长"属性值可以取两类值:

  (1)空值,表示该学生所在班级尚未选出班长;

  (2)非空值,这时该值必须是本关系中某个元组的学号值。

  三、用户定义的完整性(User-defined Integrity

  任何关系数据库系统都应该支持实体完整性和参照完整性。除此之外,不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件,用户定义的完整性就是针对某一具体关系数据库的约束条件。它反映某一具体应用所涉及的数据必须满足的语义要求。例如某个属性必须取唯一值、某个非主属性也不能取空值、某个属性的取值范围在0100之间等。关系模型应提供定义和检验这类完整性的机制,以便用统一的系统的方法处理它们,而不要由应用程序承担这一功能。

第二章 关系数据库

 

第四节 关系代数

 

  关系代数是一种抽象的查询语言,是关系数据操纵语言的一种传统表达方式,它是用对关系的运算来表达查询的。

  任何一种运算都是将一定的运算符作用于一定的运算对象上,得到预期的运算结果。所以运算对象、运算符、运算结果是运算的三大要素。

  关系代数的运算对象是关系,运算结果亦为关系。关系代数用到的运算符包括四类:集合运算符、专门的关系运算符、算术比较符和逻辑运算符。

  关系代数的运算按运算符的不同可分为传统的集合运算和专门的关系运算两类。

  其中传统的集合运算将关系看成元组的集合,其运算是从关系的"水平"方向即行的角度来进行。而专门的关系运算不仅涉及行而且涉及列。比较运算符和逻辑运算符是用来辅助专门的关系运算符进行操作的。

  2.4.1 传统的集合运算

  传统的集合运算是二目运算,包括并、差、交、广义笛卡尔积四种运算。

  2.4.2 专门的关系运算

  专门的关系运算包括选择、投影、连接、除等。为了叙述上的方便,先引入几个记号。

  下面给出这些关系运算的定义:

  1. 选择(Selection

  选择又称为限制(Restriction)。它是在关系R中选择满足给定条件的诸元组。

  2. 投影(Projection

  关系R上的投影是从R中选择出若干属性列组成新的关系。

  3. 连接(Join

  连接也称为θ连接。它是从两个关系的笛卡尔积中选取属性间满足一定条件的元组。

  4. 除(Division

  给定关系R (XY) S (YZ),其中XYZ为属性组。R中的YS中的Y可以有不同的属性名,但必须出自相同的域集。RS的除运算得到一个新的关系P(X)PR中满足下列条件的元组在X属性列上的投影:元组在X上分量值x的象集Yx包含SY上投影的集合。

  本节介绍了8种关系代数运算,其中并、差、笛卡尔积、投影和选择5种运算为基本的运算。其他3种运算,即交、连接和除,均可以用这5种基本运算来表达。引进它们并不增加语言的能力,但可以简化表达。

  关系代数中,这些运算经有限次复合后形成的式子称为关系代数表达式。

  

  关系代数语言中比较典型的例子是查询语言ISBLInformation System Base Language)。ISBL语言由IBM United Kingdom研究中心研制,用于PRTVPeterlee Relational Test Vehicle)实验系统。

 

第二章 关系数据库

 

第五节 关系演算

 

  关系演算是以数理逻辑中的谓词演算为基础的。按谓词变元的不同,关系演算可分为元组关系演算和域关系演算。本节先介绍元组关系演算,然后介绍域关系演算。在讲解时都是先介绍一种具体的语言,再讲解抽象的语言。

  2.5.1 元组关系演算语言ALPHA

  元组关系演算以元组变量作为谓词变元的基本对象。一种典型的元组关系演算语言是E.F.Codd提出的ALPHA语言。这一语言虽然没有实际实现,但关系数据库管理系统INGRES所用的QUEL语言是参照ALPHA语言研制的,与ALPHA十分类似。

  ALPHA语言主要有GETPUTHOLDUPDATEDELETEDROP 6条语句,语句的基本格式是:

   操作语句 工作空间名(表达式):操作条件

  其中表达式用于指定语句的操作对象,它可以是关系名或(和)属性名,一条语句可以同时操作多个关系或多个属性。操作条件是一个逻辑表达式,用于将操作结果限定在满足条件的元组中,操作条件可以为空。除此之外,还可以在基本格式的基础上加上排序要求,定额要求等。

  一、检索操作

  检索操作用GET语句实现。

  二、更新操作

  (1)修改操作

  修改操作用UPDATE语句实现。其步骤是:

  ① 首先用HOLD语句将要修改的元组从数据库中读到工作空间中;

  ② 然后用宿主语言修改工作空间中元组的属性;

  ③ 最后用UPDATE语句将修改后的元组送回数据库中。

  需要注意的是,单纯检索数据使用GET语句即可,但为修改数据而读元组时必须使用HOLD语句,HOLD语句是带上并发控制的GET语句。有关并发控制的概念将在第八章中详细介绍。

  (2)插入操作

  插入操作用PUT语句实现。其步骤是:

  ① 首先用宿主语言在工作空间中建立新元组;

  ② 然后用PUT语句把该元组存入指定的关系中。

  (3)删除

  删除操作用DELETE语句实现。其步骤为:

  ① HOLD语句把要删除的元组从数据库中读到工作空间中;

  ② DELETE语句删除该元组。

  2.5.2 元组关系演算

  上一节讲解了一种具体的元组关系演算语言,这一节讲解抽象的元组关系演算。

  为了讨论方便,先允许关系(的基数)是无限的。然后再对这种情况下定义的演算作适当的修改,保证关系演算中的每一个公式表示的是有限关系。

  2.5.3 域关系演算语言QBE

  关系演算的另一种形式是域关系演算。域关系演算以元组变量的分量即域变量作为谓词变元的基本对象。1975年由M.M.Zloof提出的QBE就是一个很有特色的域关系演算语言,该语言于1978年在IBM370上得以实现。QBE也指此关系数据库管理系统。

  QBEQuery By Example(即通过例子进行查询)的简称,其最突出的特点是它的操作方式。它是一种高度非过程化的基于屏幕表格的查询语言,用户通过终端屏幕编辑程序以填写表格的方式构造查询要求,而查询结果也是以表格形式显示,因此非常直观,易学易用。

  2.5.4 域关系演算

  上一节讲解了一种实际的域关系演算语言,这一节讲解抽象的域关系演算。

  域关系演算的谓词变元是域变量。

  域演算表达式的定义类似于元组演算表达式的定义,所不同的是公式中的元组变量由域变量替代。域变量是表示域的变量。关系的属性名可以视为域变量。

 

第二章 关系数据库

 

第六节 小结

 

  关系数据库系统是本书的重点。这是因为关系数据库系统是目前使用最广泛的数据库系统。20世纪70年代以后开发的数据库管理系统产品几乎都是基于关系的。更进一步,数据库领域近30年来的研究工作也主要是关系的。在数据库发展的历史上,最重要的成就是关系模型。

  关系数据库系统与非关系数据库系统的区别是,关系系统只有"表"这一种数据结构;而非关系数据库系统还有其他数据结构,对这些数据结构有其他的操作。

  关系理论的确立标志着关系数据库系统的基础研究已经接近顶峰。关系数据库系统已经占据了数据库系统的市场。

  本章系统讲解了关系数据库的重要概念,包括关系模型的数据结构、关系的完整性以及关系操作。介绍了用代数方式或逻辑方式来表达的关系语言即关系代数、元组关系演算和域关系演算。在这一章从具体到抽象,先讲解了实际的语言ALPHA(元组关系演算语言)和QBE(域关系演算语言),然后讲解了抽象的元组关系演算和域关系演算。

第三章 SQL语言

 

第一节 SQL概述

 

  SQL是一种介于关系代数与关系演算之间的结构化查询语言,其功能并不仅仅是查询。SQL是一个通用的、功能极强的关系数据库语言。

  3.1.1 SQL的特点

  SQL语言之所以能够为用户和业界所接受,并成为国际标准,是因为它是一个综合的、功能极强同时又简捷易学的语言。SQL语言集数据查询(Data Query)、数据操纵(Data Manipulation)、数据定义(Data Definition)和数据控制(Data Control)功能于一体,主要特点包括:

  一、综合统一

  数据库系统的主要功能是通过数据库支持的数据语言来实现的。

  非关系模型(层次模型、网状模型)的数据语言一般都分为模式数据定义语言(Schema Data Definition Language,简称模式DDL)、外模式数据定义语言(Subschema Data Definition Language,简称外模式DDL或子模式DDL)、与数据存储有关的描述语言(Data Storage Description Language,简称DSDL)及数据操纵语言(Data Manipulation Language,简称DML),分别用于定义模式、外模式、内模式和进行数据的存取与处置。当用户数据库投入运行后,如果需要修改模式,必须停止现有数据库的运行,转储数据,修改模式并编译后再重装数据库,十分麻烦。

  SQL语言则集数据定义语言DDL、数据操纵语言DML、数据控制语言DCL的功能于一体,语言风格统一,可以独立完成数据库生命周期中的全部活动,包括定义关系模式、插入数据建立数据库、查询、更新、维护、数据库重构、数据库安全性控制等一系列操作要求,这就为数据库应用系统的开发提供了良好的环境。用户在数据库系统投入运行后,还可根据需要随时地逐步地修改模式,且并不影响数据库的运行,从而使系统具有良好的可扩展性。

  另外,在关系模型中实体和实体间的联系均用关系表示,这种数据结构的单一性带来了数据操作符的统一,查找、插入、删除、更新等操作都只需一种操作符,从而克服了非关系系统由于信息表示方式的多样性带来的操作复杂性。例如,在DBTG中,需要两种插入操作符:STORE用来把记录存入数据库,CONNECT用来把记录插入系值以建立数据之间的联系。

  二、高度非过程化

  非关系数据模型的数据操纵语言是面向过程的语言,用其完成某项请求,必须指定存取路径。而用SQL语言进行数据操作,只要提出"做什么",而无须指明"怎么做",因此无需了解存取路径,存取路径的选择以及SQL语句的操作过程由系统自动完成。这不但大大减轻了用户负担,而且有利于提高数据独立性。

  三、面向集合的操作方式

  非关系数据模型采用的是面向记录的操作方式,操作对象是一条记录。例如查询所有平均成绩在80分以上的学生姓名,用户必须一条一条地把满足条件的学生记录找出来(通常要说明具体处理过程,即按照哪条路径,如何循环等)。而SQL语言采用集合操作方式,不仅操作对象、查找结果可以是元组的集合,而且一次插入、删除、更新操作的对象也可以是元组的集合。

  四、以同一种语法结构提供两种使用方式

  SQL语言既是自含式语言,又是嵌入式语言。作为自含式语言,它能够独立地用于联机交互的使用方式,用户可以在终端键盘上直接键入SQL命令对数据库进行操作;作为嵌入式语言,SQL语句能够嵌入到高级语言(例如CCOBOLFORTRANPL/1)程序中,供程序员设计程序时使用。而在两种不同的使用方式下,SQL语言的语法结构基本上是一致的。这种以统一的语法结构提供两种不同的使用方式的做法,提供了极大的灵活性与方便性。

  五、语言简捷,易学易用

  

  SQL语言功能极强,但由于设计巧妙,语言十分简捷,完成核心功能只用了9个动词。SQL语言接近英语口语,因此容易学习,容易使用。

  3.1.2 SQL语言的基本概念

  SQL语言支持关系数据库三级模式结构,其中外模式对应于视图(View)和部分基本表(Base Table),模式对应于基本表,内模式对应于存储文件。

  用户可以用SQL语言对基本表和视图进行查询或其他操作,基本表和视图一样,都是关系。

  基本表是本身独立存在的表,在SQL中一个关系就对应一个表。一个(或多个)基本表对应一个存储文件,一个表可以带若干索引,索引也存放在存储文件中。

  存储文件的逻辑结构组成了关系数据库的内模式。存储文件的物理结构是任意的,对用户是透明的。

  视图是从一个或几个基本表导出的表。它本身不独立存储在数据库中,即数据库中只存放视图的定义而不存放视图对应的数据,这些数据仍存放在导出视图的基本表中,因此视图是一个虚表。视图在概念上与基本表等同,用户可以在视图上再定义视图。

 

第三章 SQL语言

 

第二节 数据定义

 

  关系数据库系统支持三级模式结构,其模式、外模式和内模式中的基本对象有表、视图和索引。因此SQL的数据定义功能包括定义表、定义视图和定义索引。

  视图是基于基本表的虚表,索引是依附于基本表的,因此SQL通常不提供修改视图定义和修改索引定义的操作。用户如果想修改视图定义或索引定义,只能先将它们删除掉,然后再重建。不过有些关系数据库产品如Oracle允许直接修改视图定义。

  3.2.1 定义、删除与修改基本表

  一、定义基本表

  建立数据库最重要的一步就是定义一些基本表。SQL语言使用CREATE TABLE语句定义基本表。建表的同时通常还可以定义与该表有关的完整性约束条件,这些完整性约束条件被存入系统的数据字典中,当用户操作表中数据时由DBMS自动检查该操作是否违背这些完整性约束条件。如果完整性约束条件涉及到该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。

  二、修改基本表

  随着应用环境和应用需求的变化,有时需要修改已建立好的基本表,SQL语言用ALTER TABLE语句修改基本表。

  SQL没有提供删除属性列的语句,用户只能间接实现这一功能,即先把表中要保留的列及其内容复制到一个新表中,然后删除原表,再将新表重命名为原表名。

  三、删除基本表

  当某个基本表不再需要时,可以使用DROP TABLE语句删除它。

  基本表定义一旦删除,表中的数据、此表上建立的索引和视图都将自动被删除掉。因此执行删除基本表的操作一定要格外小心。

  注意:有的系统,如Oracle,删除基本表后建立在此表上的视图定义仍然保留在数据字典中。但是,当用户引用时就报错。

  3.2.2 建立与删除索引

  

  建立索引是加快查询速度的有效手段。用户可以根据应用环境的需要,在基本表上建立一个或多个索引,以提供多种存取路径,加快查找速度。一般说来,建立与删除索引由数据库管理员DBA或表的属主(即建立表的人)负责完成。系统在存取数据时会自动选择合适的索引作为存取路径,用户不必也不能选择索引。

  一、建立索引

  在SQL语言中,建立索引使用CREATE INDEX语句。索引可以建立在该表的一列或多列上,各列名之间用逗号分隔。每个列名后面还可以用次序指定索引值的排列次序,可选ASC(升序)或DESC(降序),缺省值为ASC

  UNIQUE表明此索引的每一个索引值只对应唯一的数据记录。

  CLUSTER表示要建立的索引是聚簇索引。所谓聚簇索引是指索引项的顺序与表中记录的物理顺序一致的索引组织。将会在Student表的Sname(姓名)列上建立一个聚簇索引,而且Student表中的记录将按照Sno值的升序存放。

  用户可以在最常查询的列上建立聚簇索引以提高查询效率。显然在一个基本表上最多只能建立一个聚簇索引。建立聚簇索引后,更新索引列数据时,往往导致表中记录的物理顺序的变更,代价较大,因此对于经常更新的列不宜建立聚簇索引。

  二、删除索引

  索引一经建立,就由系统使用和维护它,不需用户干预。建立索引是为了减少查询操作的时间,但如果数据增加删改频繁,系统会花费许多时间来维护索引。这时,可以删除一些不必要的索引。

  在SQL语言中,删除索引使用DROP INDEX语句。

  删除索引时,系统会同时从数据字典中删去有关该索引的描述。

第三章 SQL语言

 

第三节 查询

 

  数据库查询是数据库的核心操作。SQL语言提供了SELECT语句进行数据库的查询,该语句具有灵活的使用方式和丰富的功能。

  3.3.1 单表查询

  单表查询是指仅涉及一个表的查询。

  一、选择表中的若干列

  选择表中的全部列或部分列,这就是投影运算。

  二、选择表中的若干元组

  1. 消除取值重复的行

  两个本来并不完全相同的元组,投影到指定的某些列上后,可能变成相同的行了。

  三、对查询结果排序

  用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,缺省值为升序。

  四、使用集函数

  为了进一步方便用户,增强检索功能,SQL提供了许多集函数,主要有:

  COUNT 统计元组个数

  COUNT 统计一列中值的个数

  SUM 计算一列值的总和(此列必须是数值型)

  AVG 计算一列值的平均值(此列必须是数值型)

  MAX 求一列值中的最大值

  MIN 求一列值中的最小值

  如果指定DISTINCT短语,则表示在计算时要取消指定列中的重复值。如果不指定DISTINCT短语或指定ALL短语(ALL为缺省值),则表示不取消重复值。

  五、对查询结果分组

  GROUP BY子句将查询结果表按某一列或多列值分组,值相等的为一组。

  3.3.2 连接查询

  前面的查询都是针对一个表进行的。若一个查询同时涉及两个以上的表,则称之为连接查询。连接查询是关系数据库中最主要的查询,包括等值连接、自然连接、非等值连接查询、自身连接查询、外连接查询和复合条件连接查询。

  一、等值与非等值连接查询

  连接查询中用来连接两个表的条件称为连接条件或连接谓词。

  二、自身连接

  连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为表的自身连接。

  三、外连接

  在通常的连接操作中,只有满足连接条件的元组才能作为结果输出。

  四、复合条件连接

  上面各个连接查询中,WHERE子句中只有一个条件,即连接谓词。WHERE子句中可以有多个连接条件,称为复合条件连接。

  3.3.3 嵌套查询

  在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。

  一、带有IN谓词的子查询

  在嵌套查询中,子查询的结果往往是一个集合,所以谓词IN是嵌套查询中最经常使用的谓词。

  二、带有比较运算符的子查询

  带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。

  三、带有ANYALL谓词的子查询

  子查询返回单值时可以用比较运算符 ,而使用ANYALL谓词时则必须同时使用比较运算符。

  四、带有EXISTS谓词的子查询

  EXISTS代表存在量词 $。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值"true"或逻辑假值"false"。

  3.3.4 集合查询

  SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作。集合操作主要包括并操作UNION、交操作INTERSECT和差操作MINUS

第三章 SQL语言

 

第四节 数据更新

 

  SQL中数据更新包括插入数据、修改数据和删除数据三条语句。

  3.4.1 插入数据

  SQL的数据插入语句INSERT通常有两种形式。一种是插入一个元组,另一种是插入子查询结果。后者可以一次插入多个元组。

  3.4.2 修改数据

  修改操作又称为更新操作。

  一、修改某一个元组的值

  二、修改多个元组的值

  三、带子查询的修改语句

  3.4.3 删除数据

  一、删除某一个元组的值

  二、删除多个元组的值

  三、带子查询的删除语句

  四、更新操作与数据库的一致性

第三章 SQL语言

 

第五节 视图

 

  视图是关系数据库系统提供给用户以多种角度观察数据库中数据的重要机制。

  视图是从一个或几个基本表(或视图)导出的表,它与基本表不同,是一个虚表。数据库中只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。所以基本表中的数据发生变化,从视图中查询出的数据也就随之改变了。从这个意义上讲,视图就像一个窗口,透过它可以看到数据库中自己感兴趣的数据及其变化。

  视图一经定义,就可以和基本表一样被查询、被删除,我们也可以在一个视图之上再定义新的视图,但对视图的更新(增、删、改)操作则有一定的限制。

  本节专门讨论视图的定义、操作及优点。

  3.5.1 定义视图

  一、建立视图

  二、删除视图

  3.5.2 查询视图

  3.5.3 更新视图

  3.5.4 视图的作用

  视图最终是定义在基本表之上的,对视图的一切操作最终也要转换为对基本表的操作。而且对于非行列子集视图进行查询或更新时还有可能出现问题。既然如此,为什么还要定义视图呢? 这是因为合理使用视图能够带来许多好处。

  1. 视图能够简化用户的操作

  

  视图机制使用户可以将注意力集中在所关心的数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的数据查询操作。例如,那些定义了若干张表连接的视图,就将表与表之间的连接操作对用户隐蔽起来了。换句话说,用户所做的只是对一个虚表的简单查询,而这个虚表是怎样得来的,用户无需了解。

  2. 视图使用户能以多种角度看待同一数据

  视图机制能使不同的用户以不同的方式看待同一数据,当许多不同种类的用户共享同一个数据库时,这种灵活性是非常重要的。

  3. 视图对重构数据库提供了一定程度的逻辑独立性

  第一章中已经介绍过数据的物理独立性与逻辑独立性的概念。数据的物理独立性是指用户和用户程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有关系增加新的字段等,用户和用户程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全地支持。

  4. 视图能够对机密数据提供安全保护

  有了视图机制,就可以在设计数据库应用系统时,对不同的用户定义不同的视图,使机密数据不出现在不应看到这些数据的用户视图上,这样视图机制就自动提供了对机密数据的安全保护功能。例如Student表涉及三个系的学生数据,可以在其上定义三个视图,每个视图只包含一个系的学生数据,并只允许每个系的系主任查询自己系的学生视图。

第三章 SQL语言

第六节 数据控制

  由DBMS提供统一的数据控制功能是数据库系统的特点之一。SQL中数据控制功能包括事务管理功能和数据保护功能,即数据库的恢复、并发控制;数据库的安全性和完整性控制。这些概念和技术将在后面章节详细讨论。
  SQL语言定义完整性约束条件的功能主要体现在CREATE TABLE语句中,可以在该语句中定义码、取值唯一的列、不允许空值的列、外码(参照完整性)及其他一些约束条件。
  SQL语言也提供了并发控制及恢复的功能,支持事务、提交、回滚等概念,SQL语言在这方面的能力将在后面章节做进一步介绍。
  这里主要讨论SQL语言的安全性控制功能。
   某个用户对某类数据具有何种操作权力是个政策问题而不是技术问题。数据库管理系统的功能是保证这些决定的执行。为此DBMS必须具有以下功能:
  (1)把授权的决定告知系统,这是由SQLGRANTREVOKE语句来完成的。
  (2)把授权的结果存入数据字典。
  (3)当用户提出操作请求时,根据授权情况进行检查,以决定是否执行操作请求。
  3.6.1 授权
  3.6.2 收回权限

第三章 SQL语言

第七节 嵌入式SQL

  以上介绍的SQL语言是作为独立语言在终端交互方式下使用的。这是面向集合的描述性语言,是非过程性的。即大多数语句都是独立执行,与上下文无关的。而许多事务处理应用都是过程性的,需要根据不同的条件来执行不同的任务,因此单纯用SQL语言是很难实现这类应用的。
    为了解决这一问题,SQL语言提供了另一种使用方式,即将SQL语言嵌入到某种高级语言中使用,利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不足。这种方式下使用的SQL语言称为嵌入式SQLEmbedded SQL),而嵌入SQL的高级语言称为主语言或宿主语言。
  前面已经讲到,SQL的特点之一是,在两种不同的使用方式下,SQL语言的语法结构基本上是一致的。当然细节上会有许多差别,在程序设计的环境下,SQL语句要做某些必要的扩充。
  3.7.1 嵌入式SQL的一般形式
   对宿主型数据库语言SQLDBMS可采用两种方法处理,一种是预编译,另一种是修改和扩充主语言使之能处理SQL语句。目前采用较多的是预编译的方法。即由DBMS的预处理程序对源程序进行扫描,识别出SQL语句,把它们转换成主语言调用语句,以使主语言编译程序能识别它,最后由主语言的编译程序将整个源程序编译成目标码。
  在嵌入式SQL中,为了能够区分SQL语句与主语言语句,所有SQL语句都必须加前缀EXEC SQLSQL语句的结束标志则随主语言的不同而不同。
  3.7.2 嵌入式SQL语句与主语言之间的通信
    将SQL嵌入到高级语言中混合编程,SQL语句负责操纵数据库,高级语言语句负责控制程序流程。这时程序中会含有两种不同计算模型的语句,一种是描述性的面向集合的SQL语句,一种是过程性的高级语言语句,它们之间应该如何通信呢?
  数据库工作单元与源程序工作单元之间的通信主要包括:
  (1)向主语言传递SQL语句的执行状态信息,使主语言能够据此信息控制程序流程,主要用SQL通信区(SQL Communication Area,简称SQLCA)实现;
  (2)主语言向SQL语句提供参数,主要用主变量(Host Variable)实现;
  (3)将SQL语句查询数据库的结果交主语言进一步处理,主要用主变量和游标(Cursor)实现。
  一、SQL通信区
  SQL语句执行后,系统要反馈给应用程序若干信息,主要包括描述系统当前工作状态和运行环境的各种数据。这些信息将送到SQL通信区SQLCA中。应用程序从SQLCA中取出这些状态信息,据此决定接下来执行的语句。
  SQLCA是一个数据结构,在应用程序中用EXEC SQL INCLUDE SQLCA加以定义。SQLCA中有一个存放每次执行SQL语句后返回代码的变量SQLCODE。应用程序每执行完一条SQL 语句之后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理。如果SQLCODE等于预定义的常量SUCCESS,则表示SQL语句成功,否则在SQLCODE存放错误代码。
  例如,在执行删除语句DELETE后,不同的执行情况SQLCA中有下列不同的信息:
  · 成功删除,并有删除的行数(SQLCODE=SUCCESS
  · 无条件删除警告信息
  · 违反数据保护规则,拒绝操作
  · 没有满足条件的行,一行也没有删除
  · 由于各种原因,执行出错
  二、主变量
  嵌入式SQL语句中可以使用主语言的程序变量来输入或输出数据。我们把SQL语句中使用的主语言程序变量简称为主变量。
  主变量根据其作用的不同,分为输入主变量和输出主变量。输入主变量由应用程序对其赋值,SQL语句引用;输出主变量由SQL语句对其赋值或设置状态信息,返回给应用程序。一个主变量有可能既是输入主变量又是输出主变量。利用输入主变量,可以指定向数据库中插入的数据,可以将数据库中的数据修改为指定值,可以指定执行的操作,可以指定WHERE子句或HAVING子句中的条件。利用输出主变量,可以得到SQL语句的结果数据和状态。
  一个主变量可以附带一个任选的指示变量(Indicator Variable)。指示变量是一个整型变量,用来"指示"所指主变量的值或条件。指示变量可以指示输入主变量是否为空值,可以检测输出主变量是否空值,值是否被截断。
  所有主变量和指示变量必须在SQL语句BEGIN DECLARE SECTIONEND DECLARE SECTION之间进行说明。说明之后,主变量可以在SQL语句中任何一个能够使用表达式的地方出现,为了与数据库对象名(表名、视图名、列名等)区别,SQL语句中的主变量名前要加冒号(:)作为标志。同样,SQL语句中的指示变量前也必须加冒号,并且要紧跟在所指主变量之后。而在SQL语句之外,主变量和指示变量均可以直接引用,不必加冒号。
  三、游标
  SQL语言与主语言具有不同的数据处理方式。SQL语言是面向集合的,一条SQL语句原则上可以产生或处理多条记录。而主语言是面向记录的,一组主变量一次只能存放一条记录。所以仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求,为此嵌入式SQL引入了游标的概念,用游标来协调这两种不同的处理方式。游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果 ,每个游标区都有一个名字。用户可以通过游标逐一获取记录,并赋给主变量,交由主语言进一步处理。
  四、程序实例
  可以看到,在嵌入式SQL中,SQL语句与主语言语句分工非常明确。SQL语句用来直接与数据库打交道,主语言语句用来控制程序流程以及对SQL语句的执行结果做进一步加工处理。SQL语句用主变量从主语言中接收执行参数,操纵数据库;SQL语句的执行状态由DBMS送至SQLCA中;主语言程序从SQLCA中取出状态信息,据此决定下一步操作;如果SQL语句从数据库中成功地检索出数据,则通过主变量传给主语言做进一步处理。SQL语言和主语言的不同数据处理方式通过游标来协调。这实际上反映了嵌入式SQL的工作原理。
  3.7.3 不用游标的SQL语句
  不用游标的SQL语句有:
  · 说明性语句
  · 数据定义语句
  · 数据控制语句
  · 查询结果为单记录的SELECT语句
  · CURRENT形式的UPDATE语句
  · CURRENT形式的DELETE语句
  · INSERT语句
  所有的说明性语句及数据定义与控制语句都不需要使用游标。它们是嵌入式SQL中最简单的一类语句,不需要返回结果数据,也不需要使用主变量。在主语言中嵌入说明性语句及数据定义与控制语句,只要给语句加上前缀EXEC SQL和语句结束符即可。
  INSERT语句也不需要使用游标,但通常需要使用主变量。
  SELECT语句、UPDATE语句、DELETE语句则要复杂些。
  一、说明性语句
  二、数据定义语句
  三、数据控制语句
  四、查询结果为单记录的SELECT语句
  五、非CURRENT形式的UPDATE语句
  六、非CURRENT形式的DELETE语句
  七、INSERT语句
  3.7.4 使用游标的SQL语句
  必须使用游标的SQL语句有:
  · 查询结果为多条记录的SELECT语句
  · CURRENT形式的UPDATE语句
  · CURRENT形式的DELETE语句
  一、查询结果为多条记录的SELECT语句
  二、CURRENT形式的UPDATE语句和DELETE语句
  3.7.5 动态SQL简介
  在3.7.3节和3.7.4节中介绍的嵌入式SQL语句为编程提供了一定的灵活性,使用户可以在程序运行过程中根据实际需要输入WHERE子句或HAVING子句中某些变量的值。这些SQL语句的共同特点是,语句中主变量的个数与数据类型在预编译时都是确定的,只有主变量的值是程序运行过程中动态输入的,称这类嵌入式SQL语句为静态SQL语句。
  静态SQL语句提供的编程灵活性在许多情况下仍显得不足,有时候需要编写更为通用的程序。例如,对SC表,任课教师想查询选修了他所授课程的学生学号及其成绩;班主任想查询某个学生选修的课程号及相应成绩;学生想查询自己某门课程的成绩。也就是说查询条件、要查询的属性列是不确定的,这时就无法用一条静态SQL语句实现了。
  如果在预编译时下列信息不能确定,就必须使用动态SQL技术 ,如:
  (1SQL语句正文
  (2)主变量个数
  (3)主变量的数据类型
  (4SQL语句中引用的数据库对象(例如列、索引、基本表、视图等)
  动态SQL方法允许在程序运行过程中临时"组装"SQL语句,主要有三种形式:
  1. 语句可变
  允许用户在程序运行时临时输入完整的SQL语句。
  2. 条件可变
  对于非查询语句,条件子句有一定的可变性。例如删除学生选课记录,既可以是因某门课临时取消,需要删除有关该课程的所有选课记录,也可以是因为某个学生退学,需要删除该学生的所有选课记录。
  对于查询语句,SELECT子句是确定的,即语句的输出是确定的,其他子句(如WHERE子句、HAVING短语)有一定的可变性。例如查询学生人数,可以是查询某个系的学生总数,查询某个性别的学生人数,查询某个年龄段的学生人数,查询某个系某个年龄段的学生人数等,这时SELECT子句的目标列表达式是确定的(COUNT*)),但WHERE子句的条件是不确定的。
  3. 数据库对象、查询条件均可变
  对于查询语句,SELECT子句中的列名、FROM子句中的表名或视图名、WHERE子句和HAVING短语中的条件等均可由用户临时构造,即语句的输入和输出可能都是不确定的。例如前面查询学生选课关系SC的例子。对于非查询语句,涉及的数据库对象及条件也是可变的。
  这几种动态形式几乎可覆盖所有的可变要求。为了实现上述三种可变形式,SQL提供了相应的语句,例如EXECUTE IMMEDIATEPREPAREEXECUTEDESCRIBE等。使用动态SQL技术更多的是涉及程序设计方面的知识,而不是SQL语言本身,所以这里就不详细介绍了,有兴趣的读者可以参阅有关书籍。

第三章 SQL语言

第八节 小结

  本章系统而详尽地讲解了SQL语言。SQL是关系数据库语言的工业标准。各个数据库厂商支持的SQL语言在遵循标准的基础上常常作不同的扩充或修改。本章介绍的是标准SQL,因此,本章的绝大部分例子应能在不同的系统如OracleSybaseDB2 InformixSQL ServerEasybaseOpenbaseDM2Cobase等众多系统上运行,也许有的例子在某些系统上需要稍作修改后才能运行。
  在讲解了SQL语言的同时进一步讲解了关系数据库系统的基本概念,使这些概念更加具体、更加丰富。
  SQL语言可以分为数据定义、数据查询、数据更新、数据控制四大部分,有时人们把数据更新称为数据操纵,或把数据查询与数据更新合称为数据操纵。本章用很大的篇幅介绍了四部分的内容。
  
  视图是关系数据库系统中的重要概念,这是因为合理使用视图具有许多优点。
  SQL语言的数据查询功能是最丰富,也是最复杂的,读者应加强练习。

第四章 关系系统及其优化

第一节 关系系统

  在第二章比较详细地讨论了关系模型的三个基本要素:关系数据结构、关系的完整性和三类等价的关系操作。
  关系系统和关系模型是两个密切相关而又不同的概念。支持关系模型的数据库管理系统称为关系系统。这种说法很笼统,因为关系模型中并非每一部分都是同等重要的,所以并不苛求一个实际的关系数据库管理系统必须完全支持关系模型,也不苛求完全支持关系模型的系统才能称为关系系统。因此,可以给出一个关系系统的最小要求以及分类的定义。
  4.1.1 关系系统的定义
  一个系统可定义为关系系统,当且仅当它:
  (1)支持关系数据库(关系数据结构)。
  从用户观点看,数据库由表构成,并且只有表这一种结构。
  (2)支持选择、投影和(自然)连接运算,对这些运算不必要求定义任何物理存取路径。
  一个系统仅支持关系数据库而没有选择、投影和连接运算功能的,不能称为关系系统。
  
  一个系统虽然支持这三种运算,但要求定义物理存取路径,如要求用户建立索引才能按索引字段检索记录,也不能称为关系系统。
  当然并不要求关系系统的选择、投影、连接运算和关系代数的相应运算完全一样,而只要求有等价的这三种运算功能就行。
  下面对关系系统的定义做几点解释:
  (1)为什么关系系统除了要支持关系数据结构外,还必须支持选择、投影、连接运算呢?因为不支持这三种关系运算的系统,用户使用仍不方便,不能提高用户的生产率,而提高用户生产率正是关系系统的主要目标之一。
  (2)为什么要求这三种运算不能依赖于物理存取路径呢?因为依赖物理存取路径来实现关系运算就降低或丧失了数据的物理独立性。不依赖物理存取路径来实现关系运算就要求关系系统自动地选择路径。为此,系统要进行查询优化,以获得较好的性能。这正是关系系统实施的关键技术。
  (3)要求关系系统支持这三种最主要的运算而不是关系代数的全部运算功能,是因为它们是最有用的运算功能,能解决绝大部分的实际回题。
  4.1.2 关系系统的分类
  有了关系系统的定义,就可以根据它来区分哪些系统是贴了"关系型"标签的非关系系统,哪些是关系系统。当前,许多产品如DB2OracleSybaseInformixIngres是关系系统。我国自主开发的PbaseEasybase(中国人民大学)、Cobase(北京大学、中国人民大学与中软公司)、OPENBASE(东大阿尔派)、DM2(华中理工大学)等数据库管理系统是关系系统,这里不一一列举了。
  在4.1.1节中定义的关系系统是关系系统的最小要求,许多实际系统,如上面提到的那些系统都不同程度地超过了这些要求。
  4.1.3 全关系系统的十二条基本准则
  全关系型的系统应该完全地支持关系模型的所有特征,这是个原则。关系模型的奠基人E.F.Codd具体地给出了全关系型的关系系统应遵循的十二条基本准则。从实际意义上看,这十二条准则可以作为评价或购买关系型产品的标准。从理论意义上看,它是对关系数据模型的具体而又深入的论述,是从理论和实际紧密结合的高度对关系型DBMS的评述。
  准则0 一个关系型的DBMS必须能完全通过它的关系能力来管理数据库。
  准则0是下面十二条准则的基础。准则0的一个推论是:任何声称是关系型的DBMS必须在关系这个级别上支持数据的插入、修改和删除(即一次多个记录的操作级别)
  不管一个系统是否还具有非关系的管理数据的能力,它必须满足准则0。任何不满足准则0DBMS不配称为关系型DBMS
  在一些"关系型"DBMS产品的说明书中,常常建议用户"为取得可接受的性能"使用某些非关系的能力。这实际上是一种借口,表明这些系统没有为改善关系型系统的性能而进行必要的优化工作。违反准则0"关系型"DBMS给用户带来的危害是;用户不能得到真正的关系型DBMS所具有的优点。
  准则0的另一个推论是:关系型DBMS必须遵循信息准则和保证访问(存取)准则。
  准则1 信息准则。关系型DBMS的所有信息都应在逻辑一级上用一种方法即表中的值显式地表示。
  进一步地,表名、列名和域名等都用系统内部表(即数据字典表)中的值表示。数据字典本身是一个动态的用来描述元数据的关系数据库。
  满足信息准则不仅是为了提高用户的生产率,而且也是为了使软件厂商在定义其他软件包(例如应用软件辅助开发工具、专家系统等)时更加简便合理。这些软件包可以与关系型DBMS接口,并与DBMS融合成一体。这样,这些软件包能够检索存储在数据字典中的信息,需要的话可以借助DBMS的操作把新的信息存入字典中。
  要求满足信息准则的另一个原因是使得DBA维护数据库的工作更简单、更有效。因为DBA感到最困难的是用户向他们询问数据库中是否存有某种信息。一些非关系型系统的DBA往往无法对此作出确定的回答,而关系型DBMS完全可以解答这些查询。
  准则2 保证访问准则。依靠表名、主码和列名的组合,保证能以逻辑方式访问关系数据库中的每个数据项(分量值)
  访问关系数据库中的数据项可以有许多不同的逻辑方式(可能上千种),但必须保证有一种方式是可以访问每个数据单元的。这种方式独立于关系数据库的物理结构。这一点十分重要,因为在关系数据库中许多面向计算机的概念(如扫描下一个地址)已经去掉了。
  保证访问准则表明关系系统所采用的是相联寻址(Association Addressing)的访问模式,而不是那种面向机器的寻址方法,这是关系系统独有的方式。
  准则3 空值的系统化处理。全关系型的DBMS应支持空值的概念,并用系统化的方式处理空值。
  空值是"不知道""无意义"的值。在关系模型中,空值的概念很重要。例如,为了支持关系模型的完整性,要求关系的主码不能取空值。用户应该了解空值的概念和处理空值的策略。例如,当求总和、平均值等集函数时,如何处理空值将直接影响到结果。
  以往处理空值的办法常常是对每个允许取空值的字段定义一种特殊的值来表示空值。这不是系统化的好办法。因为这样的话,用户必须对每个字段或域采用不同的方法来处理空值。这种方法必然会大大降低用户生产率。而且关系语言是一种非常高级的语言,要这样做常常十分困难甚至做不到。因此必须用系统化的办法来处理空值。
  准则4 基于关系模型的动态的联机数据字典。数据库的描述在逻辑级上应该和普通数据采用同样的表示方式,使得授权用户可以使用查询一般数据所用的关系语言来查询数据库的描述信息。
  这一准则的一个推论是:每个用户(无论是应用程序员还是最终用户)只需学习一种数据模型。而非关系系统常常不具备这个优点。
  另一个推论是授权用户可以很容易地扩充数据字典,使之变成完备的主动的关系数据字典,即使厂商有时没有提供这样的数据字典。
  准则5 统一的数据子语言准则。一个关系系统可以具有几种语言和多种终端使用方式(如表格填空方式、命令方式等)。但必须有一种语言,它的语句可以表示为具有严格语法规定的字符串,并能全面地支持以下功能:
  · 数据定义、视图定义
  · 数据操作(交互式或程序式)
  · 完整性约束
  · 授权
  · 事务处理功能(事务开始、提交、滚回)
  关系方法是高度动态的,即很少需要停止数据库的活动。非关系系统则不是这样。例如,非关系系统在建立、修改数据库模式时就必须停止存取数据库的操作。因此,关系系统没有必要把上面的功能分为若干种语言(DDLDML)来实现。关系数据语言是一体化的统一的数据子语言,它使程序员可以首先交互地调试数据库语句,调试正确后再嵌入程序中。这样便大大提高了程序员的生产率。
  准则6 视图更新准则。所有理论上可更新的视图也应该允许由系统更新。
  什么叫"一个视图是理论上可更新的视图"呢?它是指对此视图的更新要求,存在一个与时间无关的算法,该算法可以无二义性地把更新要求转换为对基本表的更新序列。
  目前,有的系统只允许对基本表更新,不支持对视图的更新。有的只允许对有限的一类视图如行列子集视图更新。
  视图更新准则对于系统支持数据逻辑独立性是不可缺少的。
  准则7 高级的插入、修改和删除操作。关系系统的操作对象是单一的关系。以关系为操作对象不仅简化了用户查询,提高了用户生产率,而且也为系统提供了很大的余地来进行查询优化,提高了系统的运行效率。它允许系统来选择存取路径,以便得到最有效的运行代码。
  这条准则对于获得有效的分布式事务处理也是十分重要的。这样可以避免从远程结点传送一个记录就要发出一次请求。实现一次请求传送一个关系,从而节省了通信代价。
  准则8 数据物理独立性。无论数据库的数据在存储表示或存取方法上作任何变化,应用程序和终端活动都保持逻辑上的不变性。
  为了保证这一独立性。DBMS必须清楚明确地区分基本关系的逻辑和语义方面及其物理和效率方面、应用程序仅涉及逻辑方面。
  准则9 数据逻辑独立性。当对基本关系进行理论上信息不受损害的任何改变时,应用程序和终端活动都保持逻辑上的不变性。
  对基本关系来讲,什么样的变化在理论上是保持信息不受损害的变化呢?举两个例子来说明。把一个基本表按行的内容或者按列名分解为两个表,若这两个表都保留原基本表的主码,则这种变换在理论上是保持信息不受损失的。用无损连接方法(5.4)把两个表合成一个表也不会破坏信息的变换。
  为了尽可能提高数据逻辑独立性,DBMS必须能对理论上可更新的视图执行插入、修改和删除操作,即必须满足准则6
  数据库数据物理独立性和数据逻辑独立性给数据库设计带来了很大的好处。它使得关系数据库设计易做、易改。设计人员发现错误可随时修改而不会像非关系型DBMS中由于设计错误而造成很大损失。在开始进行关系数据库设计时,不必对应用变化、系统效率等各方面考虑周全后才进行实现工作,而可以先实施并运行数据库,当需要时再改变数据库的逻辑结构甚至物理结构。准则8和准则9保证了应用程序和终端活动都保持逻辑上的不变性。
  准则l0 数据完整性的独立性。关系数据库的完整性约束条件必须是用数据库语言定义并存储在数据字典中的,而不是在应用程序中加以定义的。
  任何关系数据库必须满足两类完整性约束条件,即实体完整性和参照完整性。此外,对于某一具体的关系数据库还需要反映业务政策和管理规章的完整性约束条件。对于一个全关系型的DBMS,这些完整性约束条件应该能用数据库语言加以定义,并能把定义存入数据字典中。它们应独立于应用程序。这样,当业务政策或管理规章变化时,只要改变存储在数据字典中的完整性定义语句而不会在逻辑上影响应用程序和终端活动。
  准则11 分布独立性。关系型DBMS具有分布独立性。
  所谓分布独立性是指关系型DBMS具有这样的数据库语言,它使应用程序和终端活动在下列情况下保持逻辑不变性:
  · 在第一次引入分布式数据时,即如果原来的DBMS只管理非分布式的数据,而现在引入了分布式数据。
  · 当数据重新分布时,即如果DBMS能管理分布式数据,现在要改变原来的数据分布。
  这两种情况概括了无论是分布的或非分布的关系型DBMS都能完全地支持这条准则。
  
  一个不支持分布式数据库的全关系型的DBMS能够加以扩充提供以上的支持,使应用程序和终端活动无论在最初的数据还是以后的数据重新分布时都能在逻辑上保持不变。关系型DBMS之所以具有这个优点,其原因是:
  (1)在分布数据时具有分解灵活性。
  (2)在组合各个结点上子事务作业的结果时具有关系操作的重组能力。
  (3)当从远程结点检索数据时可以一次请求传送一个关系,从而节省了通信代价。
  (4)由于关系数据库语言是非常高级的语言,系统可以分析查询语义,执行查询优化。而对于一次处理一个记录的数据语言,系统是无法分析查询语义的。
  准则12 无破坏准则。如果一个关系系统具有一个低级(指一次一个记录)语言,则这个低级语言不能违背或绕过完整性准则。
  在关系方法中,为获得数据完整性的独立性(准则10)就要让完整性约束条件和数据的逻辑结构相独立。用准则12就很容易帮助识别那些贴着"关系"标签的非关系系统。因为这一系统已经在关系接口之下有一个应用接口,因此很难满足准则12。这时DBA不能控制他们的数据库,不能保证数据库的完整性状态。
  以上是E.F.Codd给出的衡量一个全关系型DBMS的十二条准则。这十二条准则都以准则0为基础。但仅有准则0是不够的。不支持信息准则,不保证访问准则,不支持空值准则和数据字典准则就不能保证数据库的完整性。和早期的DBMS相比,这四条准则使数据的管理和控制(授权和完整性控制)达到了更高的标准。准则811要求全关系型DBMS具有四种独立性。其中数据的物理独立性和逻辑独立性已为大家所熟知,而数据完整性的独立性和分布独立性也已为大家重视。准则10、准则11已变得和准则8、准则9同等重要。

第四章 关系系统及其优化

第二节 关系系统数据库的查询优化

  查询优化在关系数据库系统中有着非常重要的地位。关系数据库系统和非过程化的SQL语言能够取得巨大的成功,关键是得益于查询优化技术的发展。关系查询优化是影响RDBMS性能的关键因素。
  优化对关系系统来说既是挑战又是机遇。所谓挑战是指关系系统为了达到用户可接受的性能必须进行查询优化。由于关系表达式的语义级别很高,使关系系统可以从关系表达式中分析查询语义,提供了执行查询优化的可能性。这就为关系系统在性能上接近甚至超过非关系系统提供了机遇。
  4.2.1 关系系统及其查询优化
  关系系统的查询优化既是RDBMS实现的关键技术又是关系系统的优点所在。它减轻了用户选择存取路径的负担。用户只要提出"干什么",不必指出"怎么干"。对比一下非关系系统中的情况:用户使用过程化的语言表达查询要求,执行何种记录级的操作,以及操作的序列是由用户而不是由系统来决定的。因此用户必须了解存取路径,系统要提供用户选择存取路径的手段,查询效率由用户的存取策略决定。如果用户做了愚蠢的选择,系统是无能为力对此加以改进的。这就要求用户有较高的数据库技术和程序设计水平。
  查询优化的优点不仅在于用户不必考虑如何最好地表达查询以获得较好的效率,而且在于系统可以比用户程序的"优化"做得更好。这是因为:
  (1)优化器可以从数据字典中获取许多统计信息,例如关系中的元组数、关系中每个属性值的分布情况等。优化器可以根据这些信息选择有效的执行计划,而用户程序则难以获得这些信息。
  (2)如果数据库的物理统计信息改变了,系统可以自动对查询进行重新优化以选择相适应的执行计划。在非关系系统中必须重写程序,而重写程序在实际应用中往往是不太可能的。
  (3)优化器可以考虑数百种不同的执行计划,而程序员一般只能考虑有限的几种可能性。
  (4)优化器中包括了很多复杂的优化技术,这些优化技术往往只有最好的程序员才能掌握。系统的自动优化相当于使得所有人都拥有这些优化技术。
  关系数据库查询优化的总目标是:选择有效的策略,求得给定关系表达式的值。
  实际系统对查询优化的具体实现不尽相同,但一般来说,可以归纳为四个步骤:
   将查询转换成某种内部表示,通常是语法树。
   根据一定的等价变换规则把语法树转换成标准(优化)形式。
   选择低层的操作算法。对于语法树中的每一个操作需要根据存取路径、数据的存储分布、存储数据的聚簇等信息来选择具体的执行算法。
   生成查询计划。查询计划也称查询执行方案,是由一系列内部操作组成的。这些内部操作按一定的次序构成查询的一个执行方案。通常这样的执行方案有多个,需要对每个执行计划计算代价,从中选择代价最小的一个。在集中式关系数据库中,计算代价时主要考虑磁盘读写的I/O次数,也有一些系统还考虑了CPU的处理时间。
  步骤和步骤实际上没有清晰的界限,有些系统是作为一个步骤处理的。对于一个查询可能会有很多候选的查询计划,因此应采取适当的启发式技术来缩减查询计划的搜索空间。另外由于统计信息的不精确性,中间结果的大小难以预计等因素使得代价的精确估计常常比较困难。
  目前的商品化RDBMS大都采用基于代价的优化算法。这种方法要求优化器充分考虑系统中的各种参数(如缓冲区大小、表的大小、数据的分布、存取路径等),通过某种代价模型计算出各种查询执行方案的执行代价,然后选取代价最小的执行方案。在集中式数据库中,查询的执行开销主要包括:
  总代价 = I/O代价 + CPU代价
  在多用户环境下,内存在多个用户间的分配情况会明显地影响这些用户查询执行的总体性能。例如,如果系统分配给某个用户大量的内存用于其查询处理,这固然会加速该用户查询的执行,但是却可能使系统内的其他用户得不到足够的内存而影响其查询处理速度。因此,多用户数据库还应考虑查询的内存开销,即:
  总代价 = I/O代价 + CPU代价 + 内存代价
  4.2.2 一个实例
  4.2.3 查询优化的一般准则
  下面的优化策略一般能提高查询效率,但不一定是所有策略中最优的。其实"优化"一词并不确切,也许"改进""改善"更恰当些。
  1. 选择运算应尽可能先做。在优化策略中这是最重要、最基本的一条。它常常可使执行时节约几个数量级,因为选择运算一般使计算的中间结果大大变小。
  2. 在执行连接前对关系适当地预处理。预处理方法主要有两种,在连接属性上建立索引和对关系排序,然后执行连接。第一种称为索引连接方法;第二种称为排序合并(SORT-MERGE)连接方法。
  3. 把投影运算和选择运算同时进行。如有若干投影和选择运算,并且它们都对同一个关系操作,则可以在扫描此关系的同时完成所有的这些运算以避免重复扫描关系。
  4. 把投影同其前或其后的双目运算结合起来,没有必要为了去掉某些字段而扫描一遍关系。
  5. 把某些选择同在它前面要执行的笛卡尔积结合起来成为一个连接运算,连接特别是等连接运算要比同样关系上的笛卡尔积省很多时间(4.2.2节中的实例)
  6. 找出公共子表达式。如果这种重复出现的子表达式的结果不是很大的关系,并且从外存中读入这个关系比计算该子表达式的时间少得多,则先计算一次公共子表达式并把结果写入中间文件是合算的。当查询的是视图时,定义视图的表达式就是公共子表达式的情况。
  4.2.4 关系代数等价变换规则
  上面的优化策略大部分都涉及到代数表达式的变换。在第二、三章中介绍了各种查询语言,这些语言都可以转换成关系代数表达式。因此关系代数表达式的优化是查询优化的基本课题。而研究关系代数表达式的优化最好从研究关系表达式的等价变换规则开始。所谓关系代数表达式的等价是指用相同的关系代替两个表达式中相应的关系所得到的结果是相同的。
  4.2.5 关系代数表达式的优化算法
  应用上面的变换法则来优化关系表达式,使优化后的表达式能遵循4.2.3节中的一般原则。例如把选择和投影尽可能地早做(即把它们移到表达式语法树的下部)。下面给出关系表达式的优化算法。
  4.2.6 优化的一般步骤
  各个关系系统的优化方法不尽相同,大致的步骤可以归纳如下:
  (1)把查询转换成某种内部表示
  (2)把语法树转换成标准(优化)形式
  (3)选择低层的存取路径
  (4)生成查询计划,选择代价最小的

第四章 关系系统及其优化

第三节 小结

  支持关系模型的数据库系统是关系系统,由于支持关系模型的程度不同,实际的数据库系统可以分为表式系统、(最小)关系系统、关系完备的和全关系的四类系统。
  完全地支持关系模型的系统应遵循十二条基本准则,这是关系模型的奠基人E.F.Codd提出的。这十二条准则也可以作为评价或购买关系型产品的标准。
  查询处理是数据库管理系统的核心,而查询优化技术又是查询处理的关键技术。查询优化一般可分为代数优化和物理优化。代数优化是指关系代数表达式的优化;物理优化则是指
  
  存取路径和低层操作算法的选择。

第五章 关系数据理论

第一节 问题的提出

  前面已经讨论了数据库系统的一般概念,介绍了关系数据库的基本概念、关系模型的三个部分以及关系数据库的标准语言。但是还有一个很基本的问题尚未涉及,针对一个具体问题,应该如何构造一个适合于它的数据模式,即应该构造几个关系模式,每个关系由哪些属性组成等。这是数据库设计的问题,确切地讲是关系数据库逻辑设计问题。
  实际上设计任何一种数据库应用系统,不论是层次的、网状的还是关系的,都会遇到如何构造合适的数据模式即逻辑结构的问题。由于关系模型有严格的数学理论基础,并且可以向别的数据模型转换,因此,人们就以关系模型为背景来讨论这个问题,形成了数据库逻辑设计的一个有力工具——关系数据库的规范化理论。规范化理论虽然是以关系模型为背景,但是它对于一般的数据库逻辑设计同样具有理论上的意义。
  下面首先回顾一下关系模型的形式化定义。
  在2.2.2节中已经讲过,一个关系通常是由赋予它的元组语义来确定的。元组语义实质上是一个n目谓词(n是属性集中属性的个数)。凡使该n目谓词为真的笛卡尔积中的元素(或者说凡符合元组语义的那部分元素)的全体就构成了该关系模式的关系。
  
  现实世界随着时间在不断地变化,因而在不同的时刻,关系模式的关系也会有所变化。但是,现实世界的许多已有事实限定了关系模式所有可能的关系必须满足一定的完整性约束条件。这些约束或者通过对属性取值范围的限定,或者通过属性值间的相互关连(主要体现于值的相等与否)反映出来。后者称为数据依赖,它是数据模式设计的关键。关系模式应当刻划这些完整性约束条件,于是一个关系模式应当是一个五元组。
  RUDdomF
  这里:
  (1)关系名R,它是符号化的元组语义;
  (2)一组属性U
  (3)属性组U中属性所来自的域D
  (4)属性到域的映射dom
  (5)属性组U上的一组数据依赖F
  由于(3),(4)对模式设计关系不大,因此在本章中把关系模式看作是一个三元组:
  R(UF)
  当且仅当U上的一个关系r满足F时,r称为关系模式R(UF)的一个关系。
  关系,作为一张二维表,对它有一个最起码的要求:每一个分量必须是不可分的数据项。满足了这个条件的关系模式就属于第一范式(1NF)。
  在模式设计中,假设已知一个模式,它仅由单个关系模式组成,问题是要设计一个模式SD,它与Sφ"等价"。但在某些指定的方面"更好"一些。这里通过一个例子来说明一个"不好"的模式会有些什么毛病,分析它们产生的原因,从中找出设计一个""的关系模式的办法。
  在举例之前,先非形式地讨论一下数据依赖的概念。
  数据依赖是通过一个关系中属性间值的相等与否体现出来的数据间的相互关系。它是现实世界属性间相互联系的抽象,是数据内在的性质,是语义的体现。现在人们已经提出了许多种类型的数据依赖,其中最重要的是函数依赖(Functional Dependency,简称FD)和多值依赖(Multivalued Dependency,简称MVD)。
  函数依赖极为普遍地存在于现实生活中。比如描述一个学生的关系,可以有学号(SNO),姓名(SNAME),系名(SDEPT)等几个属性。由于一个学号只对应一个学生,一个学生只在一个系学习。因而当"学号"值确定之后,姓名和该生所在系的值也就被唯一地确定了。就象自变量x确定之后,相应的函数值fx)也就唯一地确定了一样,称SNO函数决定SNAMESDEPT,或者说SNAMESDEPT函数依赖于SNO,记为SNO→SNAMESNO→SDEPT
  现在要建立一个数据库来描述学生的一些情况,面临的对象有:学生(用学号SNO描述),系(用系名SDEPT描述),系负责人(用其姓名MN描述),课程(用课程名CNAME描述)和成绩(G)。于是得到一组属性。
   U = { SNOSDEPTMNCNAMEG }
  由现实世界的已知事实得知
   一个系有若干学生,但一个学生只属于一个系;
   一个系只有一名(正职)负责人;
   一个学生可以选修多门课程,每门课程有若干学生选修;
   每个学生学习每一门课程有一个成绩;
  于是得到属性组U上的一组函数依赖:
   F = { SNO→SDEPTSDEPT→MN,(SNOCNAME→G }
  如果只考虑函数依赖这一种数据依赖,就得到了一个描述学校的数据库模式SUF),它由一个单一的关系模式构成。这个模式有下述三个"毛病"
  (1)如果一个系刚成立尚无学生,或者虽然有了学生但尚未安排课程。那么就无法把这个系及其负责人的信息存入数据库。称为插入异常。
  (2)反过来,如果某个系的学生全部毕业了,在删除该系学生选修课程的同时,把这个系及其负责人的信息也丢掉了,称为删除异常。
  (3)冗余太大。比如,每一个系负责人的姓名要与该系每一个学生的每一门功课的成绩出现的次数一样多。这样,一方面浪费存储,另一方面系统要付出很大的代价来维护数据库的完整性。比如某系负责人更换后,就必须逐一修改有关的每一个元组。
  由于上述三个"毛病",它是一个"不好"的数据库模式。一个""的模式应当不会发生插入异常和删除异常、冗余应尽可能少。
  为什么会发生插入异常和删除异常呢?
  这是因为这个模式中的函数依赖存在某些不好的性质。假如把这个单一的模式改造一下,分成三个关系模式:
  SSNOSDEPTSNO→SDEPT);
  SGSNOCNAMEG,(SNOCNAME→G);
  DEPTSDEPTMNSDEPT→MN);
  这三个模式都不会发生插入异常、删除异常的毛病,数据的冗余也得到了控制。
  一个模式的函数依赖会有哪些不好的性质,如何改造一个不好的模式,这就是下一节规范化理论讨论的内容。

第五章 关系数据理论

第二节 规范化

  为了使数据库设计的方法走向完备,人们研究了规范化理论。从1971年起E.F.Codd就提出了这一理论,规范化理论的研究已经取得了很多成果。
   前面已经提过关系必须是规范化的(Normalization),即每一个分量必须是不可分的数据项。但是这只是最基本的规范化。上节的例子说明并非所有这样规范化的关系都能很好地描述现实世界,必须作进一步的分析,以确定如何设计一个好的、反映现实世界的模式。
  本节将讨论下述内容:首先讨论一个关系属性间不同的依赖情况,讨论如何根据属性间依赖情况来判定关系是否具有某些不合适的性质。通常按属性间依赖情况来区分关系规范化的程度为第一范式、第二范式、第三范式和第四范式等。然后直观地描述如何将具有不合适性质的关系转换为更合适的形式。
  5.2.1 函数依赖
  5.2.2
  5.2.3 范式
  5.2.4 2NF
  5.2.5 3NF
  5.2.6 BCNF
  5.2.7 多值依赖
  5.2.8 4NF
  5.2.9 规范化小结
  在关系数据库中,对关系模式的基本要求是满足第一范式。这样的关系模式就是合法的、允许的。但是,人们发现有些关系模式存在插入、删除异常、修改复杂,数据冗余等毛病。人们寻求解决这些问题的方法,这就是规范化的目的。
  
  规范化的基本思想是逐步消除数据依赖中不合适的部分,使模式中的各关系模式达到某种程度的"分离",即"一事一地"的模式设计原则。让一个关系描述一个概念、一个实体或者实体间的一种联系。若多于一个概念就把它"分离"出去。因此所谓规范化实质上是概念的单一化。

第五章 关系数据理论

第三节 数据依赖的公理系统

  数据依赖的公理系统是模式分解算法的理论基础,下面首先讨论函数依赖的一个有效而完备的公理系统——Armstrong公理系统。
  为了求得给定关系模式的码,为了从一组函数依赖求得蕴含的函数依赖,例如已知函数依赖集F,要问X→Y是否为F所蕴含,就需要一套推理规则,这组推理规则是l974年首先由Armstrong提出来的。
  Armstrong公理系统 U为属性集总体,FU上的一组函数依赖, 于是有关系模式R (UF )。对R (UF ) 来说有以下的推理规则:
  · Al.自反律(Reflexivity):若Y 属于 X属于U,则X →YF所蕴含。
  · A2.增广律(Augmentation):若X→YF所蕴含,且Z 属于U,则XZ→YZ F所蕴含。
  · A3.传递律(Transitivity):若X→YY→ZF所蕴含,则X→ZF所蕴含。
  注意:由自反律所得到的函数依赖均是平凡的函数依赖,自反律的使用并不依赖于F

第五章 关系数据理论

第四节 模式的分解

  在对函数依赖的基本性质有了初步的了解之后,可以具体地来讨论模式的分解了。
  5.4.1 模式分解的三个定义
  对于一个模式的分解是多种多样的,但是分解后产生的模式应与原模式等价。
  人们从不同的角度去观察问题,对"等价"的概念形成了三种不同的定义:
  · 分解具有"无损连接性"Lossless join)。
  · 分解要"保持函数依赖"Preserve dependency)。
  · 分解既要"保持函数依赖",又要具有"无损连接性"
  这三个定义是实行分解的三条不同的准则。按照不同的分解准则,模式所能达到的分离程度各不相同,各种范式就是对分离程度的测度。
  
  这一节要讨论的问题是:
  (1"无损连接性""保恃函数依赖"的含义是什么?如何判断?
  (2)对于不同的分解等价定义,究竟能达到何种程度的分离,即分离后的关系模式是第几范式。
  (3)如何实现分离,即给出分解的算法。
  先来看两个例子,说明按定义5.l6,若只要求R(UF) 分解后的各关系模式所含属性的""等于U,这个限定是很不够的。
  一个关系分解为多个关系,相应地原来存储在一张二维表内的数据就要分散存储到多张二维表中,要使这个分解有意义,起码的要求是后者不能丢失前者的信息。
  5.4.2 分解的无损连接性和保持函数依赖性
  5.4.3 模式分解的算法
  关于模式分解的几个重要事实是:
  (1)若要求分解保持函数依赖,那么模式分离总可以达到3NF,但不一定能达到BCNF
  (2)若要求分解既保持函数依赖,又具有无损连接性,可以达到3NF,但不一定能达到BCNF
  (3)若要求分解具有无损连接性,那一定可达到4NF
  它们分别由算法5.3、算法5.4、算法5.5、算法5.6来实现。

第五章 关系数据理论

第五节 小结

  在整个讨论过程中,只采用了两种关系运算——投影和自然连接。并且总是从一个关系模式出发,而不是从一组关系模式出发实行分解。"等价"的定义也是一组关系模式与一个关系模式的"等价",这就是说,在开始讨论问题时事实上已经假设了存在着一个单一的关系模式,这就是泛关系假设。
  本章一开始,就指出这是研究模式设计的一种特殊情况:"假设已知一个模式,它仅由单个关系模式组成,问题是要设计一个模式SD,它与Sφ'等价',但在某些方面更好一些"
  泛关系假设是运用规范化理论时的障碍,因为承认了泛关系假设,就等于承认了现实世界各实体间只能有一种联系,而这常常是办不到的。比如工人与机器之间就可以存在"使用""维护"等多种联系。对此,人们提出了一些办法,希望解决这个矛盾。例如建立一个不受泛关系假设限制的理论,或者采用某些手段使现实世界向信息世界转换时适合于泛关系的要求。
  最后应当强调的是,规范化理论为数据库设计提供了理论的指南和工具,但仅仅是指南和工具。并不是规范化程度越高,模式就越好,而必须结合应用环境和现实世界的具体情况合理地选择数据库模式。

第六章 数据库设计

第一节 数据库设计概述

  人们在总结信息资源开发、管理和服务的各种手段时,认为最有效的是数据库技术。数据库的应用已越来越广泛。从小型的单项事务处理系统到大型复杂的信息系统大都用先进的数据库技术来保持系统数据的整体性、完整性和共享性。目前,一个国家的数据库建设规模(指数据库的个数、种类)、数据库信息量的大小和使用频度已成为衡量这个国家信息化程度的重要标志之一。
  数据库设计是建立数据库及其应用系统的技术,是信息系统开发和建设中的核心技术,具体说,数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。这个问题是数据库在应用领域的主要研究课题。
  在数据库领域内,常常把使用数据库的各类系统统称为数据库应用系统。
  6.1.1 数据库和信息系统
  从使用者角度看,信息系统是提供信息、辅助人们对环境进行控制和进行决策的系统。数据库是信息系统的核心和基础。它把信息系统中大量的数据按一定的模型组织起来,提供存储、维护、检索数据的功能,使信息系统可以方便、及时、准确地从数据库中获得所需的信息。一个信息系统的各个部分能否紧密地结合在一起以及如何结合,关键在数据库。因此只有对数据库进行合理的逻辑设计和有效的物理设计才能开发出完善而高效的信息系统。数据库设计是信息系统开发和建设的重要组成部分。
  
  大型数据库的设计和开发是一项庞大的工程,是涉及多学科的综合性技术。其开发周期长、耗资多、失败的风险也大。必须把软件工程的原理和方法应用到数据库建设中来。对于从事数据库设计的专业人员来讲,应该具备多方面的技术和知识。主要有:
  · 数据库的基本知识和数据库设计技术;
  · 计算机科学的基础知识和程序设计的方法和技巧;
  · 软件工程的原理和方法;
  · 应用领域的知识。
  其中应用领域的知识随着应用系统所属的领域不同而不同。数据库设计人员必须深入实际与用户密切结合,对应用环境、专业业务有具体深入的了解才能设计出符合具体领域要求的数据库应用系统。
  6.1.2 数据库设计的特点
  数据库设计既是一项涉及多学科的综合性技术又是一项庞大的工程项目。有人讲"三分技术,七分管理,十二分基础数据"是数据库建设的基本规律,这是有一定道理的。技术与管理的界面(称之为"干件")十分重要。数据库建设是硬件、软件和干件的结合。这是数据库设计的特点之一。这里着重讨论软件设计的技术。
  数据库设计应该和应用系统设计相结合,也就是说,整个设计过程中要把结构(数据)设计和行为(处理)设计密切结合起来。这是数据库设计的特点之二。
  传统的软件工程忽视对应用中数据语义的分析和抽象。例如结构化设计(Structure Design,简称SD方法)和逐步求精的方法着重于处理过程的特性,只要有可能就尽量推迟数据结构设计的决策。这种方法显然对于数据库应用系统是不妥的。数据库模式是各应用程序共享的结构,是稳定的,永久的,不像以文件系统为基础的应用系统,文件是某一应用程序私用的。数据库设计质量的好坏直接影响系统中各个处理过程的性能和质量。
   早期的数据库设计致力于数据模型和建模方法研究,着重结构特性的设计而忽视了对行为的设计。也就是说比较重视在给定的应用环境下,采用什么原则、方法来建造数据库的结构,而没有考虑应用环境要求与数据库结构的关系,因此结构设计与行为设计是分离的。
  在数据库设计中如何把结构特性和行为特性相结合,许多学者和专家进行了探讨和实践(见本章参考文献[9][23])。
  6.1.3 数据库设计方法简述
  由于信息结构复杂,应用环境多样,在相当长的一段时期内数据库设计主要采用手工试凑法。使用这种方法与设计人员的经验和水平有直接关系,数据库设计成为一种技艺而不是工程技术,缺乏科学理论和工程方法的支持,工程的质量难以保证,常常是数据库运行一段时间后又不同程度地发现各种问题,增加了系统维护的代价。十余年来,人们努力探索,提出了各种数据库设计方法,这些方法运用软件工程的思想和方法,提出了各种设计准则和规程,都属于规范设计法。
  规范设计法中比较著名的有新奥尔良(New Orleans)方法。它将数据库设计分为四个阶段:需求分析(分析用户要求)、概念设计(信息分析和定义)、逻辑设计(设计实现)和物理设计(物理数据库设计)。其后,S.B.Yao等又将数据库设计分为五个步骤。又有I.R.Palmer等主张把数据库设计当成一步接一步的过程,并采用一些辅助手段实现每一过程。
  基于E-R模型的数据库设计方法,基于3NF(第三范式)的设计方法,基于抽象语法规范的设计方法等,是在数据库设计的不同阶段上支持实现的具体技术和方法。
  规范设计法从本质上看仍然是手工设计方法,其基本思想是过程迭代和逐步求精。
  数据库工作者和数据库厂商一直在研究和开发数据库设计工具。经过十多年的努力,数据库设计工具已经实用化和产品化。例如Design 2000 PowerDesigner 分别是ORACLE公司和SYBASE公司推出的数据库设计工具软件。这些工具软件可以自动地或辅助设计人员完成数据库设计过程中的很多任务。人们已经越来越认识到自动数据库设计工具的重要性。特别是大型数据库的设计需要自动设计工具的支持。人们也日益认识到数据库设计和应用设计应该同时进行,目前许多计算机辅助软件工程(Computer Aided Sofeware Engineering,简称CASE)工具已经开始强调这两个方面。
  6.1.4 数据库设计的基本步骤
  按照规范设计的方法,考虑数据库及其应用系统开发全过程,将数据库设计分为以下六个阶段(如图6.2所示)
  · 需求分析;
  · 概念结构设计;
  · 逻辑结构设计;
  · 物理结构设计;
  · 数据库实施;
  · 数据库运行和维护。
  数据库设计开始之前,首先必须选定参加设计的人员,包括系统分析人员、数据库设计人员和程序员、用户和数据库管理员。系统分析和数据库设计人员是数据库设计的核心人员,他们将自始至终参与数据库设计,他们的水平决定了数据库系统的质量。用户和数据库管理员在数据库设计中也是举足轻重的,他们主要参加需求分析和数据库的运行维护,他们的积极参与不但能加速数据库设计,而且也是决定数据库设计的质量的重要因素。程序员则在系统实施阶段参与进来,分别负责编制程序和准备软硬件环境。
  如果所设计的数据库应用系统比较复杂,还应该考虑是否需要使用数据库设计工具和CASE工具以提高数据库设计质量并减少设计工作量,以及选用何种工具。
  1. 需求分析阶段
  进行数据库设计首先必须准确了解与分析用户需求(包括数据与处理)。需求分析是整个设计过程的基础,是最困难、最耗费时间的一步。作为地基的需求分析是否做得充分与准确,决定了在其上构建数据库大厦的速度与质量。需求分析做得不好,甚至会导致整个数据库设计返工重做。
  2. 概念结构设计阶段
  概念结构设计是整个数据库设计的关键,它通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型。
  3. 逻辑结构设计阶段
  逻辑结构设计是将概念结构转换为某个DBMS所支持的数据模型,并对其进行优化。
  4. 数据库物理设计阶段
  数据库物理设计是为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储结构和存取方法)。
  5. 数据库实施阶段
  在数据库实施阶段,设计人员运用DBMS提供的数据语言及其宿主语言,根据逻辑设计和物理设计的结果建立数据库,编制与调试应用程序,组织数据入库,并进行试运行。
  6. 数据库运行和维护阶段
  数据库应用系统经过试运行后即可投入正式运行。在数据库系统运行过程中必须不断地对其进行评价、调整与修改。
  设计一个完善的数据库应用系统是不可能一蹴而就的,它往往是上述六个阶段的不断反复。
  需要指出的是,这个设计步骤既是数据库设计的过程,也包括了数据库应用系统的设计过程。在设计过程中把数据库的设计和对数据库中数据处理的设计紧密结合起来,将这两个方面的需求分析、抽象、设计、实现在各个阶段同时进行,相互参照,相互补充,以完善两方面的设计。事实上,如果不了解应用环境对数据的处理要求,或没有考虑如何去实现这些处理要求,是不可能设计一个良好的数据库结构的。

第六章 数据库设计

第二节 需求分析

  需求分析简单地说就是分析用户的要求。需求分析是设计数据库的起点,需求分析的结果是否准确地反映了用户的实际要求,将直接影响到后面各个阶段的设计,并影响到设计结果是否合理和实用。
  6.2.1 需求分析的任务
  需求分析的任务是通过详细调查现实世界要处理的对象(组织、部门、企业等),充分了解原系统(手工系统或计算机系统)工作概况,明确用户的各种需求,然后在此基础上确定新系统的功能。新系统必须充分考虑今后可能的扩充和改变,不能仅仅按当前应用需求来设计数据库。
  调查的重点是"数据""处理",通过调查、收集与分析,获得用户对数据库如下要求:
  (1)信息要求。指用户需要从数据库中获得信息的内容与性质。由信息要求可以导出数据要求,即在数据库中需要存储哪些数据。
  (2)处理要求。指用户要完成什么处理功能,对处理的响应时间有什么要求,处理方式是批处理还是联机处理。
  (3)安全性与完整性要求。
  确定用户的最终需求是一件很困难的事,这是因为一方面用户缺少计算机知识,开始时无法确定计算机究竟能为自己做什么,不能做什么,因此往往不能准确地表达自己的需求,所提出的需求往往不断地变化。另一方面,设计人员缺少用户的专业知识,不易理解用户的真正需求,甚至误解用户的需求。因此设计人员必须不断深入地与用户交流,才能逐步确定用户的实际需求。
  6.2.2 需求分析的方法
  进行需求分析首先是调查清楚用户的实际要求,与用户达成共识,然后分析与表达这些需求。
  调查用户需求的具体步骤是:
  (1)调查组织机构情况。包括了解该组织的部门组成情况、各部门的职责等,为分析信息流程做准备。
  (2)调查各部门的业务活动情况。包括了解各个部门输入和使用什么数据,如何加工处理这些数据,输出什么信息,输出到什么部门,输出结果的格式是什么,这是调查的重点。
  (3)在熟悉了业务活动的基础上,协助用户明确对新系统的各种要求,包括信息要求、处理要求、完全性与完整性要求,这是调查的又一个重点。
  (4)确定新系统的边界。对前面调查的结果进行初步分析,确定哪些功能由计算机完成或将来准备让计算机完成,哪些活动由人工完成。由计算机完成的功能就是新系统应该实现的功能。
  在调查过程中,可以根据不同的问题和条件,使用不同的调查方法。常用的调查方法有:
  (1)跟班作业。通过亲身参加业务工作来了解业务活动的情况。这种方法可以比较准确地理解用户的需求,但比较耗费时间。
  (2)开调查会。通过与用户座谈来了解业务活动情况及用户需求。座谈时,参加者之间可以相互启发。
  (3)请专人介绍。
  (4)询问。对某些调查中的问题,可以找专人询问。
  (5)设计调查表请用户填写。如果调查表设计得合理,这种方法是很有效,也易于为用户接受。
  (6)查阅记录。查阅与原系统有关的数据记录。
  做需求调查时,往往需要同时采用上述多种方法。但无论使用何种调查方法,都必须有用户的积极参与和配合。
  在调查了解了用户需求以后,还需要进一步分析和表达用户的需求。在众多的分析方法中结构化分析方法(Structured Analysis,简称SA方法)是一种简单实用的方法。SA方法从最上层的系统组织机构入手,采用自顶向下、逐层分解的方式分析系统。
  6.2.3 数据字典
  数据流图表达了数据和处理的关系,数据字典则是系统中各类数据描述的集合,是进行详细的数据收集和数据分析所获得的主要成果。数据字典在数据库设计中占有很重要的地位。
  数据字典通常包括数据项、数据结构、数据流、数据存储和处理过程五个部分。其中数据项是数据的最小组成单位,若干个数据项可以组成一个数据结构,数据字典通过对数据项和数据结构的定义来描述数据流、数据存储的逻辑内容。
  1. 数据项
  数据项是不可再分的数据单位。对数据项的描述通常包括以下内容:
  数据项描述={数据项名,数据项含义说明,别名,数据类型,长度,取值范围,
  取值含义,与其他数据项的逻辑关系,数据项之间的联系}
  其中"取值范围""与其他数据项的逻辑关系"(例如该数据项等于另几个数据项的和,该数据项值等于另一数据项的值等)定义了数据的完整性约束条件,是设计数据检验功能的依据。
  可以用关系规范化理论为指导,用数据依赖的概念分析和表示数据项之间的联系。即按实际语义,写出每个数据项之间的数据依赖,它们是数据库逻辑设计阶段数据模型优化的依据。
  2. 数据结构
  数据结构反映了数据之间的组合关系。一个数据结构可以由若干个数据项组成,也可以由若干个数据结构组成,或由若干个数据项和数据结构混合组成。对数据结构的描述通常包括以下内容:
  数据结构描述={数据结构名,含义说明,组成:{数据项或数据结构}}
  3. 数据流
  数据流是数据结构在系统内传输的路径。对数据流的描述通常包括以下内容:
  数据流描述={数据流名,说明,数据流来源,数据流去向,
         组成:{数据结构},平均流量,高峰期流量}
  其中"数据流来源"是说明该数据流来自哪个过程。"数据流去向"是说明该数据流将到哪个过程去。"平均流量"是指在单位时间(每天、每周、每月等)里的传输次数。"高峰期流量"则是指在高峰时期的数据流量。
  4. 数据存储
  
  数据存储是数据结构停留或保存的地方,也是数据流的来源和去向之一。它可以是手工文档或手工凭单,也可以是计算机文档。对数据存储的描述通常包括以下内容:
  数据存储描述={数据存储名,说明,编号,输入的数据流,输出的数据流,
          组成:{数据结构},数据量,存取频度,存取方式}
  其中"存取频度"指每小时或每天或每周存取几次、每次存取多少数据等信息。"存取方式"包括是批处理还是联机处理;是检索还是更新;是顺序检索还是随机检索等。另外,"输入的数据流"要指出其来源,"输出的数据流"要指出其去向。
  5. 处理过程
  处理过程的具体处理逻辑一般用判定表或判定树来描述。数据字典中只需要描述处理过程的说明性信息,通常包括以下内容:
  处理过程描述={处理过程名,说明,输入:{数据流},输出:{数据流},
          处理:{简要说明}}
  其中"简要说明"中主要说明该处理过程的功能及处理要求。功能是指该处理过程用来做什么(而不是怎么做),处理要求包括处理频度要求,如单位时间里处理多少事务、多少数据量、响应时间要求等。这些处理要求是后面物理设计的输入及性能评价的标准。
  可见,数据字典是关于数据库中数据的描述,即元数据,而不是数据本身。
  数据字典是在需求分析阶段建立,在数据库设计过程中不断修改、充实、完善的。
  明确地把需求收集和分析作为数据库设计的第一阶段是十分重要的。这一阶段收集到的基础数据(用数据字典来表达)和一组数据流程图(Data Flow Diagram,简称DFD)是下一步进行概念设计的基础。
   最后,要强调两点:
   1)需求分析阶段的一个重要而困难的任务是收集将来应用所涉及的数据,设计人员应充分考虑到可能的扩充和改变,使设计易于更改,系统易于扩充,这是第一点。
   2)必须强调用户的参与,这是数据库应用系统设计的特点。数据库应用系统和广泛的用户有密切的联系,许多人要使用数据库。数据库的设计和建立又可能对更多人的工作环境产生重要影响。因此用户的参与是数据库设计不可分割的一部分。在数据分析阶段,任何调查研究没有用户的积极参加是寸步难行的。设计人员应该和用户取得共同的语言,帮助不熟悉计算机的用户建立数据库环境下的共同概念,并对设计工作的最后结果承担共同的责任。

第六章 数据库设计

第三节 概念结构设计

  将需求分析得到的用户需求抽象为信息结构即概念模型的过程就是概念结构设计。它是整个数据库设计的关键。
  6.3.1 概念结构
  在需求分析阶段所得到的应用需求应该首先抽象为信息世界的结构,才能更好地、更准确地用某一DBMS实现这些需求。
  概念结构的主要特点是:
  (1)能真实、充分地反映现实世界,包括事物和事物之间的联系,能满足用户对数据的处理要求。是对现实世界的一个真实模型。
  (2)易于理解,从而可以用它和不熟悉计算机的用户交换意见,用户的积极参与是数据库的设计成功的关键。
  (3)易于更改,当应用环境和应用要求改变时,容易对概念模型修改和扩充。
  (4)易于向关系、网状、层次等各种数据模型转换。
  概念结构是各种数据模型的共同基础,它比数据模型更独立于机器、更抽象,从而更加稳定。
  描述概念模型的有力工具是E-R模型。有关E-R模型的基本概念已在第一章介绍。下面将用E-R模型来描述概念结构。
  6.3.2 概念结构设计的方法与步骤
  设计概念结构通常有四类方法:
  · 自顶向下。即首先定义全局概念结构的框架,然后逐步细化。
  · 自底向上。即首先定义各局部应用的概念结构,然后将它们集成起来,得到全局概念结构。
  · 逐步扩张。首先定义最重要的核心概念结构,然后向外扩充,以滚雪球的方式逐步生成其他概念结构,直至总体概念结构。
  · 混合策略。即将自顶向下和自底向上相结合,用自顶向下策略设计一个全局概念结构的框架,以它为骨架集成由自底向上策略中设计的各局部概念结构。
  其中最经常采用的策略是自底向上方法。即自顶向下地进行需求分析,然后再自底向上地设计概念结构。
  这里只介绍自底向上设计概念结构的方法。它通常分为两步:第1步是抽象数据并设计局部视图,第2步是集成局部视图,得到全局的概念结构。
  6.3.3 数据抽象与局部视图设计
  概念结构是对现实世界的一种抽象。所谓抽象是对实际的人、物、事和概念进行人为处理,抽取所关心的共同特性,忽略非本质的细节,并把这些特性用各种概念精确地加以描述,这些概念组成了某种模型。
  6.3.4 视图的集成
  各子系统的分E-R图设计好以后,下一步就是要将所有的分E-R图综合成一个系统的总E-R图。
  一、合并分E-R图,生成初步E-R
  二、消除不必要的冗余,设计基本E-R

第六章 数据库设计

第四节 逻辑结构设计

  概念结构是独立于任何一种数据模型的信息结构。逻辑结构设计的任务就是把概念结构设计阶段设计好的基本E-R图转换为与选用DBMS产品所支持的数据模型相符合的逻辑结构。
  从理论上讲,设计逻辑结构应该选择最适于相应概念结构的数据模型,然后对支持这种数据模型的各种DBMS进行比较,从中选出最合适的DBMS。但实际情况往往是已给定了某种DBMS,设计人员没有选择的余地。目前DBMS产品一般支持关系、网状、层次三种模型中的某一种,对某一种数据模型,各个机器系统又有许多不同的限制,提供不同的环境与工具。所以设计逻辑结构时一般要分三步进行:
  (1)将概念结构转换为一般的关系、网状、层次模型;
  (2)将转换来的关系、网状、层次模型向特定DBMS支持下的数据模型转换;
  (3)对数据模型进行优化。
  6.4.1 E-R图向关系模型的转换
  E-R图向关系模型的转换要解决的问题是如何将实体和实体间的联系转换为关系模式,如何确定这些关系模式的属性和码。
  关系模型的逻辑结构是一组关系模式的集合。E-R图则是由实体、实体的属性和实体之间的联系三个要素组成的。所以将E-R图转换为关系模型实际上就是要将实体、实体的属性和实体之间的联系转换为关系模式,这种转换一般遵循如下原则:
  一个实体型转换为一个关系模式。实体的属性就是关系的属性,实体的码就是关系的码。
  对于实体间的联系则有以下不同的情况:
  (1)一个11联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,每个实体的码均是该关系的候选码。如果与某一端实体对应的关系模式合并,则需要在该关系模式的属性中加入另一个关系模式的码和联系本身的属性。
  (2)一个1n联系可以转换为一个独立的关系模式,也可以与n端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为n端实体的码。
  (3)一个mn联系转换为一个关系模式。与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。
  (4)三个或三个以上实体间的一个多元联系可以转换为一个关系模式。与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。
  (6)具有相同码的关系模式可合并。
  形成了一般的数据模型后,下一步就是向特定的RDBMS的模型转换。设计人员必须熟悉所用RDBMS的功能与限制。这一步是依赖于机器的,不能给出一个普遍的规则,但对于关系模型来说,这种转换通常都比较简单,不会有太多的困难。
  6.4.2 数据模型的优化
  数据库逻辑设计的结果不是唯一的。为了进一步提高数据库应用系统的性能,还应该根据应用需要适当地修改、调整数据模型的结构,这就是数据模型的优化。关系数据模型的优化通常以规范化理论为指导,方法为:
  1. 确定数据依赖。在6.2.3"数据字典"一节中已讲到用数据依赖分析和表示数据项之间的联系,写出每个数据项之间的数据依赖。如果需求分析阶段没有来得及做,可以现在补做,即按需求分析阶段所得到的语义,分别写出每个关系模式内部各属性之间的数据依赖以及不同关系模式属性之间的数据依赖。
  2. 对于各个关系模式之间的数据依赖进行极小化处理,消除冗余的联系,具体方法已在6.3.4中讲解。
  3. 按照数据依赖的理论对关系模式逐一进行分析,考察是否存在部分函数依赖、传递函数依赖、多值依赖等,确定各关系模式分别属于第几范式。
  4. 按照需求分析阶段得到的处理要求,分析对于这样的应用环境这些模式是否合适,确定是否要对某些模式进行合并或分解。
  必须注意的是,并不是规范化程度越高的关系就越优。例如,当查询经常涉及到两个或多个关系模式的属性时,系统经常进行连接运算。连接运算的代价是相当高的,可以说关系模型低效的主要原因就是连接运算引起的。这时可以考虑将这几个关系合并为一个关系。因此在这种情况下,第二范式甚至第一范式也许是合适的。
  又如,非BCNF的关系模式虽然从理论上分析会存在不同程度的更新异常或冗余,但如果在实际应用中对此关系模式只是查询,并不执行更新操作,则就不会产生实际影响。所以对于一个具体应用来说,到底规范化到什么程度,需要权衡响应时间和潜在问题两者的利弊决定。
  5. 对关系模式进行必要的分解, 提高数据操作的效率和存储空间的利用率。常用的两种分解方法是水平分解和垂直分解。
  水平分解是把(基本)关系的元组分为若干子集合,定义每个子集合为一个子关系,以提高系统的效率。 根据"80/20原则",一个大关系中,经常被使用的数据只是关系的一部分,约20%,可以把经常使用的数据分解出来,形成一个子关系。 如果关系R上具有n个事务,而且多数事务存取的数据不相交,则R可分解为少于或等于n个子关系,使每个事务存取的数据对应一个关系。
  垂直分解是把关系模式R的属性分解为若干子集合,形成若干子关系模式。垂直分解的原则是,经常在一起使用的属性从R中分解出来形成一个子关系模式。垂直分解可以提高某些事务的效率,但也可能使另一些事务不得不执行连接操作,从而降低了效率。因此是否进行垂直分解取决于分解后R上的所有事务的总效率是否得到了提高。垂直分解需要确保无损连接性和保持函数依赖,即保证分解后的关系具有无损连接性和保持函数依赖性。这可以用第五章中的模式分解算法对需要分解的关系模式进行分解和检查。
  规范化理论为数据库设计人员判断关系模式优劣提供了理论标准,可用来预测模式可能出现的问题,使数据库设计工作有了严格的理论基础。
  6.4.3 设计用户子模式
  
  将概念模型转换为全局逻辑模型后,还应该根据局部应用需求,结合具体DBMS的特点,设计用户的外模式。
  目前关系数据库管理系统一般都提供了视图(View)概念,可以利用这一功能设计更符合局部用户需要的用户外模式。
  定义数据库全局模式主要是从系统的时间效率、空间效率、易维护等角度出发。由于用户外模式与模式是相对独立的,因此在定义用户外模式时可以注重考虑用户的习惯与方便。包括:
  (1)使用更符合用户习惯的别名
  在合并各分E-R图时,曾做了消除命名冲突的工作,以使数据库系统中同一关系和属性具有唯一的名字。这在设计数据库整体结构时是非常必要的。用View机制可以在设计用户View时重新定义某些属性名,使其与用户习惯一致,以方便使用。
  (2)可以对不同级别的用户定义不同的View,以保证系统的安全性。
  假设有关系模式产品(产品号,产品名,规格,单价,生产车间,生产负责人,产品成本,产品合格率,质量等级),可以在产品关系上建立两个视图:
  为一般顾客建立视图:
  产品1(产品号,产品名,规格,单价)
  为产品销售部门建立图:
  产品2(产品号,产品名,规格,单价,车间,生产负责人)
  顾客视图中只包含允许顾客查询的属性;销售部门视图中只包含允许销售部门查询的属性。生产领导部门则可以查询全部产品数据。这样就可以防止用户非法访问本来不允许他们查询的数据,保证了系统的安全性。
  (3)简化用户对系统的使用
  如果某些局部应用中经常要使用某些很复杂的查询,为了方便用户,可以将这些复杂查询定义为视图,用户每次只对定义好的视图进行查询,大大简化了用户的使用。

第六章 数据库设计

第五节 数据库的物理设计

  数据库在物理设备上的存储结构与存取方法称为数据库的物理结构,它依赖于给定的计算机系统。为一个给定的逻辑数据模型选取一个最适合应用要求的物理结构的过程,就是数据库的物理设计。
  数据库的物理设计通常分为两步:
  (1)确定数据库的物理结构,在关系数据库中主要指存取方法和存储结构;
  (2)对物理结构进行评价,评价的重点是时间和空间效率。
  如果评价结果满足原设计要求,则可进入到物理实施阶段,否则,就需要重新设计或修改物理结构,有时甚至要返回逻辑设计阶段修改数据模型。
  6.5.1 数据库的物理设计的内容和方法
  不同的数据库产品所提供的物理环境、存取方法和存储结构有很大差别,能供设计人员使用的设计变量、参数范围也很不相同,因此没有通用的物理设计方法可遵循,只能给出一般的设计内容和原则。希望设计优化的物理数据库结构,使得在数据库上运行的各种事务响应时间小、存储空间利用率高、事务吞吐率大。为此首先对要运行的事务进行详细分析,获得选择物理数据库设计所需要的参数。其次,要充分了解所用RDBMS的内部特征,特别是系统提供的存取方法和存储结构。
  对于数据库查询事务,需要得到如下信息:
  · 查询的关系;
  · 查询条件所涉及的属性;
  · 连接条件所涉及的属性;
  · 查询的投影属性。
  对于数据更新事务,需要得到如下信息:
  · 被更新的关系;
  · 每个关系上的更新操作条件所涉及的属性;
  · 修改操作要改变的属性值。
  除此之外,还需要知道每个事务在各关系上运行的频率和性能要求。例如,事务T必须在10秒钟内结束,这对于存取方法的选择具有重大影响。
  上述这些信息是确定关系的存取方法的依据。
  应注意的是,数据库上运行的事务会不断变化、增加或减少,以后需要根据上述设计信息的变化调整数据库的物理结构。
  通常对于关系数据库物理设计的内容主要包括
  · 为关系模式选择存取方法;
  · 设计关系、索引等数据库文件的物理存储结构。
  下面就介绍这些设计内容和方法。
  6.5.2 关系模式存取方法选择
  数据库系统是多用户共享的系统,对同一个关系要建立多条存取路径才能满足多用户的多种应用要求。物理设计的任务之一就是要确定选择哪些存取方法,即建立哪些存取路径。
  存取方法是快速存取数据库中数据的技术。数据库管理系统一般都提供多种存取方法。常用的存取方法有三类。第一类是索引方法,目前主要是B+树索引方法;第二类是聚簇(Cluster)方法;第三类是HASH方法。
  B+树索引方法是数据库中经典的存取方法,使用最普遍。
  一、索引存取方法的选择
  所谓选择索引存取方法实际上就是根据应用要求确定对关系的哪些属性列建立索引、哪些属性列建立组合索引、哪些索引要设计为唯一索引等。一般来说:
  1. 如果一个(或一组)属性经常在查询条件中出现,则考虑在这个(或这组)属性上建立索引(或组合索引)
  2. 如果一个属性经常作为最大值和最小值等聚集函数的参数,则考虑在这个属性上建立索引;
  3. 如果一个(或一组)属性经常在连接操作的连接条件中出现,则考虑在这个(或这组)属性上建立索引;
  关系上定义的索引数并不是越多越好,系统为维护索引要付出代价,查找索引也要付出代价。例如,若一个关系的更新频率很高,这个关系上定义的索引数不能太多。因为更新一个关系时,必须对这个关系上有关的索引做相应的修改。
  二、聚簇存取方法的选择
  为了提高某个属性(或属性组)的查询速度,把这个或这些属性(称为聚簇码)上具有相同值的元组集中存放在连续的物理块称为聚簇。
  聚簇功能可以大大提高按聚簇码进行查询的效率。例如要查询信息系的所有学生名单,设信息系有500名学生,在极端情况下,这500名学生所对应的数据元组分布在500个不同的物理块上。尽管对学生关系已按所在系建有索引,由索引很快找到了信息系学生的元组标识,避免了全表扫描,然而再由元组标识去访问数据块时就要存取500个物理块,执行500I/O操作。如果将同一系的学生元组集中存放,则每读一个物理块可得到多个满足查询条件的元组,从而显著地减少了访问磁盘的次数。
  聚簇功能不但适用于单个关系,也适用于经常进行连接操作的多个关系。即把多个连接关系的元组按连接属性值聚集存放,聚簇中的连接属性称为聚簇码。这就相当于把多个关系按"预连接"的形式存放,从而大大提高连接操作的效率。
  一个数据库可以建立多个聚簇,一个关系只能加入一个聚簇。
  选择聚簇存取方法,即确定需要建立多少个聚簇,每个聚簇中包括哪些关系。
  下面先设计候选聚簇,一般来说:
  (1)对经常在一起进行连接操作的关系可以建立聚簇;
  (2)如果一个关系的一组属性经常出现在相等比较条件中,则该单个关系可建立聚簇;
  (3)如果一个关系的一个(或一组)属性上的值重复率很高,则此单个关系可建立聚簇。即对应每个聚簇码值的平均元组数不太少。太少了,聚簇的效果不明显。
  然后检查候选聚簇中的关系,取消其中不必要的关系。
  (1)从聚簇中删除经常进行全表扫描的关系;
  (2)从聚簇中删除更新操作远多于连接操作的关系;
  (3)不同的聚簇中可能包含相同的关系,一个关系可以在某一个聚簇中,但不能同时加入多个聚簇。要从这多个聚簇方案(包括不建立聚簇)中选择一个较优的,即在这个聚簇上运行各种事务的总代价最小。
  必须强调的是,聚簇只能提高某些应用的性能,而且建立与维护聚簇的开销是相当大的。对已有关系建立聚簇,将导致关系中元组移动其物理存储位置,并使此关系上原有的索引无效,必须重建。当一个元组的聚簇码值改变时,该元组的存储位置也要做相应移动,聚簇码值要相对稳定,以减少修改聚簇码值所引起的维护开销。
  因此,当通过聚簇码进行访问或连接是该关系的主要应用,与聚簇码无关的其他访问很少或者是次要的,这时可以使用聚簇。尤其当SQL语句中包含有与聚簇码有关的ORDER BYGROUP BYUNIONDISTINCT等子句或短语时,使用聚簇特别有利,可以省去对结果集的排序操作;否则很可能会适得其反。
  三、HASH存取方法的选择
  有些数据库管理系统提供了HASH存取方法。选择HASH存取方法的规则如下:
  如果一个关系的属性主要出现在等连接条件中或主要出现在相等比较选择条件中,而且满足下列两个条件之一,则此关系可以选择HASH存取方法:
  (1)如果一个关系的大小可预知,而且不变;
  (2)如果关系的大小动态改变,而且数据库管理系统提供了动态HASH存取方法。
  6.5.3 确定数据库的存储结构
  确定数据库物理结构主要指确定数据的存放位置和存储结构,包括确定关系、索引、聚簇、日志、备份等的存储安排和存储结构;确定系统配置等。
  确定数据的存放位置和存储结构要综合考虑存取时间、存储空间利用率和维护代价三方面的因素。这三个方面常常是相互矛盾的,因此需要进行权衡,选择一个折中方案。
  1. 确定数据的存放位置
  为了提高系统性能,应该根据应用情况将数据的易变部分与稳定部分、经常存取部分和存取频率较低部分分开存放。
  例如,目前许多计算机都有多个磁盘,因此可以将表和索引放在不同的磁盘上,在查询时,由于两个磁盘驱动器并行工作,可以提高物理I/O读写的效率;也可以将比较大的表分放在两个磁盘上,以加快存取速度,这在多用户环境下特别有效;还可以将日志文件与数据库对象(表、索引等)放在不同的磁盘上以改进系统的性能。此外,数据库的数据备份和日志文件备份等只在故障恢复时才使用,而且数据量很大,可以存放在磁带上。
  由于各个系统所能提供的对数据进行物理安排的手段、方法差异很大,因此设计人员应仔细了解给定的RDBMS提供的方法和参数,针对应用环境的要求,对数据进行适当的物理安排。
  2. 确定系统配置
  DBMS产品一般都提供了一些系统配置变量、存储分配参数,供设计人员和DBA对数据库进行物理优化。初始情况下,系统都为这些变量赋予了合理的缺省值。但是这些值不一定适合每一种应用环境,在进行物理设计时,需要重新对这些变量赋值,以改善系统的性能。
  系统配置变量很多,例如:同时使用数据库的用户数,同时打开的数据库对象数,内存分配参数,缓冲区分配参数(使用的缓冲区长度、个数),存储分配参数,物理块的大小,物理块装填因子,时间片大小,数据库的大小,锁的数目,等等。这些参数值影响存取时间和存储空间的分配,在物理设计时就要根据应用环境确定这些参数值,以使系统性能最佳。
  在物理设计时对系统配置变量的调整只是初步的,在系统运行时还要根据系统实际运行情况做进一步的调整,以期切实改进系统性能。
  6.5.4 评价物理结构
  数据库物理设计过程中需要对时间效率、空间效率、维护代价和各种用户要求进行权衡,其结果可以产生多种方案,数据库设计人员必须对这些方案进行细致的评价,从中选择一个较优的方案作为数据库的物理结构。
  评价物理数据库的方法完全依赖于所选用的DBMS,主要是从定量估算各种方案的存储空间、存取时间和维护代价入手,对估算结果进行权衡、比较,选择出一个较优的合理的物理结构。如果该结构不符合用户需求,则需要修改设计。

第六章 数据库设计

第六节 数据库的实施和维护

  完成数据库的物理设计之后,设计人员就要用RDBMS提供的数据定义语言和其他实用程序将数据库逻辑设计和物理设计结果严格描述出来,成为DBMS可以接受的源代码,再经过调试产生目标模式。然后就可以组织数据入库了,这就是数据库实施阶段。
  6.6.1 数据的载入和应用程序的调试
  数据库实施阶段包括两项重要的工作,一项是数据的载入,另一项是应用程序的编码和调试。
  一般数据库系统中,数据量都很大,而且数据来源于部门中的各个不同的单位,数据的组织方式、结构和格式都与新设计的数据库系统有相当的差距,组织数据录入就要将各类源数据从各个局部应用中抽取出来,输入计算机,再分类转换,最后综合成符合新设计的数据库结构的形式,输入数据库。因此这样的数据转换、组织入库的工作是相当费力费时的工作。
  特别是原系统是手工数据处理系统时,各类数据分散在各种不同的原始表格、凭证、单据之中。在向新的数据库系统中输入数据时,还要处理大量的纸质文件,工作量就更大。
  
  由于各个不同的应用环境差异很大,不可能有通用的转换器,DBMS产品也不提供通用的转换工具。为提高数据输入工作的效率和质量,应该针对具体的应用环境设计一个数据录入子系统,由计算机来完成数据入库的任务。
  由于要入库的数据在原来的系统中的格式结构与新系统中不完全一样,有的差别可能还比较大,不仅向计算机内输入数据时发生错误,转换过程中也有可能出错。因此在源数据入库之前要采用多种方法对它们进行检验,以防止不正确的数据入库,这部分的工作在整个数据输入子系统中是非常重要的。
  在设计数据输入子系统时还要注意原有系统的特点,例如对原有系统是人工数据处理系统的情况,尽管新系统的数据结构可能与原系统有很大差别,在设计数据输入子系统时,尽量让输入格式与原系统结构相近,这不仅使处理手工文件比较方便,更重要的是减少用户出错的可能性,保证数据输入的质量。现有的DBMS一般都提供不同DBMS之间数据转换的工具,若原来是数据库系统,就可以利用新系统的数据转换工具,先将原系统中的表转换成新系统中相同结构的临时表,再将这些表中的数据分类、转换、综合成符合新系统的数据模式,插入相应的表中。
  数据库应用程序的设计应该与数据库设计同时进行,因此在组织数据入库的同时还要调试应用程序。应用程序的设计、编码和调试的方法、步骤在软件工程等课程中有详细讲解,这里就不赘述了。
  6.6.2 数据库的试运行
  在原有系统的数据有一小部分已输入数据库后,就可以开始对数据库系统进行联合调试,这又称为数据库的试运行。
  这一阶段要实际运行数据库应用程序,执行对数据库的各种操作,测试应用程序的功能是否满足设计要求。如果不满足,对应用程序部分则要修改、调整,直到达到设计要求为止。
  在数据库试运行时,还要测试系统的性能指标,分析其是否达到设计目标。在对数据库进行物理设计时已初步确定了系统的物理参数值,但一般的情况下,设计时的考虑在许多方面只是近似的估计,和实际系统运行总有一定的差距,因此必须在试运行阶段实际测量和评价系统性能指标。事实上,有些参数的最佳值往往是经过运行调试后找到的。如果测试的结果与设计目标不符,则要返回物理设计阶段,重新调整物理结构,修改系统参数,某些情况下甚至要返回逻辑设计阶段,修改逻辑结构。
  这里特别要强调两点,第一,上面已经讲到组织数据入库是十分费时费力的事,如果试运行后还要修改数据库的设计,还要重新组织数据入库。因此应分期分批地组织数据入库,先输入小批量数据做调试用,待试运行基本合格后,再大批量输入数据,逐步增加数据量,逐步完成运行评价。
  第二,在数据库试运行阶段,由于系统还不稳定,硬、软件故障随时都可能发生。而系统的操作人员对新系统还不熟悉,误操作也不可避免,因此应首先调试运行DBMS的恢复功能,做好数据库的转储和恢复工作。一旦故障发生,能使数据库尽快恢复,尽量减少对数据库的破坏。
  6.6.3 数据库的运行和维护
  数据库试运行合格后,数据库开发工作就基本完成,即可投入正式运行了。但是,由于应用环境在不断变化,数据库运行过程中物理存储也会不断变化,对数据库设计进行评价、调整、修改等维护工作是一个长期的任务,也是设计工作的继续和提高。
  在数据库运行阶段,对数据库经常性的维护工作主要是由DBA完成的,它包括:
  1. 数据库的转储和恢复
  数据库的转储和恢复是系统正式运行后最重要的维护工作之一。DBA要针对不同的应用要求制定不同的转储计划,以保证一旦发生故障能尽快将数据库恢复到某种一致的状态,并尽可能减少对数据库的破坏。
  2. 数据库的安全性、完整性控制
  在数据库运行过程中,由于应用环境的变化,对安全性的要求也会发生变化,比如有的数据原来是机密的,现在是可以公开查询的了,而新加入的数据又可能是机密的了。系统中用户的密级也会改变。这些都需要DBA根据实际情况修改原有的安全性控制。同样,数据库的完整性约束条件也会变化,也需要DBA不断修正,以满足用户要求。
  3. 数据库性能的监督、分析和改造
  在数据库运行过程中,监督系统运行,对监测数据进行分析,找出改进系统性能的方法是DBA的又一重要任务。目前有些DBMS产品提供了监测系统性能参数的工具,DBA可以利用这些工具方便地得到系统运行过程中一系列性能参数的值。DBA应仔细分析这些数据,判断当前系统运行状况是否是最佳,应当做哪些改进。例如调整系统物理参数,或对数据库进行重组织或重构造等。
  4. 数据库的重组织与重构造
  数据库运行一段时间后,由于记录不断增、删、改,会使数据库的物理存储情况变坏,降低了数据的存取效率,数据库性能下降,这时DBA就要对数据库进行重组织,或部分重组织(只对频繁增、删的表进行重组织)。DBMS一般都提供数据重组织用的实用程序。在重组织的过程中,按原设计要求重新安排存储位置、回收垃圾、减少指针链等,提高系统性能。
  数据库的重组织,并不修改原设计的逻辑和物理结构,而数据库的重构造则不同,它是指部分修改数据库的模式和内模式。
  
  由于数据库应用环境发生变化,增加了新的应用或新的实体,取消了某些应用,有的实体与实体间的联系也发生了变化等,使原有的数据库设计不能满足新的需求,需要调整数据库的模式和内模式。例如,在表中增加或删除某些数据项,改变数据项的类型,增加或删除某个表,改变数据库的容量,增加或删除某些索引等。当然数据库的重构也是有限的,只能做部分修改。如果应用变化太大,重构也无济于事,说明此数据库应用系统的生命周期已经结束,应该设计新的数据库应用系统了。

第六章 数据库设计

第七节 小结

  数据库设计这一章主要讨论数据库设计的方法和步骤,列举了较多的实例,详细介绍了数据库设计各个阶段的目标、方法、应注意的事项。其中的重点是概念结构的设计和逻辑结构的设计,这也是数据库设计过程中最重要的两个环节。学习这一章,要努力掌握书中讨论的基本方法,还要能在实际工作中运用这些思想,设计符合应用需求的数据库应用系统。

第七章 数据库恢复技术

第一节 事务的基本概念

  在讨论数据库恢复技术之前先讲解事务的基本概念和事务的性质。
  一、事务(Transaction)
  所谓事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。例如,在关系数据库中,一个事务可以是一条SQL语句、一组SQL语句或整个程序。
  事务和程序是两个概念。一般地讲,一个程序中包含多个事务。
  事务的开始与结束可以由用户显式控制。如果用户没有显式地定义事务,则由DBMS按缺省规定自动划分事务。在SQL语言中,定义事务的语句有三条:
  BEGIN TRANSACTION
  COMMIT
  ROLLBACK
  
  事务通常是以BEGIN TRANSACTION开始,以COMMITROLLBACK结束。COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束。ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销,滚回到事务开始时的状态。这里的操作指对数据库的更新操作。
  二、事务的特性
  事务具有四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这个四个特性也简称为ACID特性。
  1. 原子性
  事务是数据库的逻辑工作单位,事务中包括的诸操作要么都做,要么都不做。
  2. 一致性
  事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。例如某公司在银行中有AB两个账号,现在公司想从账号A中取出一万元,存入账号B。那么就可以定义一个事务,该事务包括两个操作,第一个操作是从账号A中减去一万元,第二个操作是向账号B中加入一万元。这两个操作要么全做,要么全不做。全做或者全不做,数据库都处于一致性状态。如果只做一个操作则用户逻辑上就会发生错误,少了一万元,这时数据库就处于不一致性状态。可见一致性与原子性是密切相关的。
  3. 隔离性
  一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
  4. 持续性
  持续性也称永久性(Permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其执行结果有任何影响。
  事务是恢复和并发控制的基本单位。所以下面的讨论均以事务为对象。
  
  保证事务ACID特性是事务处理的重要任务。事务ACID特性可能遭到破坏的因素有:
  (1)多个事务并行运行时,不同事务的操作交叉执行;
  (2)事务在运行过程中被强行停止。
  在第一种情况下,数据库管理系统必须保证多个事务的交叉运行不影响这些事务的原子性。在第二种情况下,数据库管理系统必须保证被强行终止的事务对数据库和其他事务没有任何影响。
  这些就是数据库管理系统中恢复机制和并发控制机制的责任。

第七章 数据库恢复技术

第二节 数据库恢复概述

  尽管数据库系统中采取了各种保护措施来防止数据库的安全性和完整性被破坏,保证并发事务的正确执行,但是计算机系统中硬件的故障、软件的错误、操作员的失误以及恶意的破坏仍是不可避免的,这些故障轻则造成运行事务非正常中断,影响数据库中数据的正确性,重则破坏数据库,使数据库中全部或部分数据丢失,因此数据库管理系统必须具有把数据库从错误状态恢复到某一已知的正确状态(亦称为一致状态或完整状态)的功能,这就是数据库的恢复。恢复子系统是数据库管理系统的一个重要组成部分,而且还相当庞大,常常占整个系统代码的百分之十以上。数据库系统所采用的恢复技术是否行之有效,不仅对系统的可靠程度起着决定性作用,而且对系统的运行效率也有很大影响,是衡量系统性能优劣的重要指标。

第七章 数据库恢复技术

第三节 故障的种类

  数据库系统中可能发生各种各样的故障,大致可以分以下几类:
  一、事务内部的故障
  事务内部的故障有的是可以通过事务程序本身发现的(见下面转账事务的例子),有的是非预期的,不能由事务程序处理的。
  事务内部更多的故障是非预期的,是不能由应用程序处理的。如运算溢出、并发事务发生死锁而被选中撤销该事务、违反了某些完整性限制等。以后,事务故障仅指这类非预期的故障。
  事务故障意味着事务没有达到预期的终点(COMMIT或者显式的ROLLBACK),因此,数据库可能处于不正确状态。恢复程序要在不影响其他事务运行的情况下,强行回滚(ROLLBACK)该事务,即撤销该事务已经作出的任何对数据库的修改,使得该事务好像根本没有启动一样。
  这类恢复操作称为事务撤销(UNDO)。
  二、系统故障
  系统故障是指造成系统停止运转的任何事件,使得系统要重新启动。例如,特定类型的硬件错误(CPU故障)、操作系统故障、DBMS代码错误、突然停电等。这类故障影响正在运行的所有事务,但不破坏数据库。这时主存内容,尤其是数据库缓冲区(在内存)中的内容都被丢失,所有运行事务都非正常终止。发生系统故障时,一些尚未完成的事务的结果可能已送入物理数据库,从而造成数据库可能处于不正确的状态。为保证数据一致性,需要清除这些事务对数据库的所有修改。
  
  恢复子系统必须在系统重新启动时让所有非正常终止的事务回滚,强行撤销(UNDO)所有未完成事务。
  另一方面,发生系统故障时,有些已完成的事务可能有一部分甚至全部留在缓冲区,尚未写回到磁盘上的物理数据库中,系统故障使得这些事务对数据库的修改部分或全部丢失,这也会使数据库处于不一致状态,因此应将这些事务已提交的结果重新写入数据库。所以系统重新启动后,恢复子系统除需要撤销所有未完成事务外,还需要重做(REDO)所有已提交的事务,以将数据库真正恢复到一致状态。
  三、介质故障
  系统故障常称为软故障(Soft Crash),介质故障称为硬故障(Hard Crash)。硬故障指外存故障,如磁盘损坏、磁头碰撞,瞬时强磁场干扰等。这类故障将破坏数据库或部分数据库,并影响正在存取这部分数据的所有事务。这类故障比前两类故障发生的可能性小得多,但破坏性最大。
  四、计算机病毒
  计算机病毒是一种人为的故障或破坏,是一些恶作剧者研制的一种计算机程序。这种程序与其他程序不同,它像微生物学所称的病毒一样可以繁殖和传播,并造成对计算机系统包括数据库的危害。
  病毒的种类很多,不同病毒有不同的特征。小的病毒只有20条指令,不到50B。大的病毒像一个操作系统,有上万条指令组成。
  有的病毒传播很快,一旦侵入系统就马上摧毁系统;有的病毒有较长的潜伏期,机器在感染后数天或数月才开始发病;有的病毒感染系统所有的程序和数据;有的只对某些特定的程序和数据感兴趣。多数病毒一开始并不摧毁整个计算机系统,它们只在数据库中或其他数据文件中将小数点向左或向右移一移,增加或删除一两个"0"
  计算机病毒已成为计算机系统的主要威胁,自然也是数据库系统的主要威胁。为此计算机的安全工作者已研制了许多预防病毒的"疫苗",检查、诊断、消灭计算机病毒的软件也在不断发展。但是,至今还没有一种使得计算机"终生"免疫的疫苗。因此数据库一旦被破坏仍要用恢复技术把数据库加以恢复。
  总结各类故障,对数据库的影响有两种可能性。一是数据库本身被破坏。二是数据库没有破坏,但数据可能不正确,这是因为事务的运行被非正常终止造成的。
  恢复的基本原理十分简单。可以用一个词来概括:冗余。这就是说,数据库中任何一部分被破坏的或不正确的数据可以根据存储在系统别处的冗余数据来重建。尽管恢复的基本原理很简单但实现技术的细节却相当复杂,下面略去一些细节,介绍数据库恢复的实现技术。

第七章 数据库恢复技术

第四节 恢复的实现技术

  恢复机制涉及的两个关键问题是:第一,如何建立冗余数据;第二,如何利用这些冗余数据实施数据库恢复。
  建立冗余数据最常用的技术是数据转储和登录日志文件。通常在一个数据库系统中,这两种方法是一起使用的。
  7.4.1 数据转储
  数据转储是数据库恢复中采用的基本技术。所谓转储即DBA定期地将整个数据库复制到磁带或另一个磁盘上保存起来的过程。这些备用的数据文本称为后备副本或后援副本。
  当数据库遭到破坏后可以将后备副本重新装入,但重装后备副本只能将数据库恢复到转储时的状态,要想恢复到故障发生时的状态,必须重新运行自转储以后的所有更新事务。
  转储是十分耗费时间和资源的,不能频繁进行。DBA应该根据数据库使用情况确定一个适当的转储周期。
  转储可分为静态转储和动态转储。
  静态转储是在系统中无运行事务时进行的转储操作。即转储操作开始的时刻,数据库处于一致性状态,而转储期间不允许(或不存在)对数据库的任何存取、修改活动。显然,静态转储得到的一定是一个数据一致性的副本。
  静态转储简单,但转储必须等待正运行的用户事务结束才能进行,同样,新的事务必须等待转储结束才能执行。显然,这会降低数据库的可用性。
  动态转储是指转储期间允许对数据库进行存取或修改。即转储和用户事务可以并发执行。
  动态转储可克服静态转储的缺点,它不用等待正在运行的用户事务结束,也不会影响新事务的运行。但是,转储结束时后援副本上的数据并不能保证正确有效。例如,在转储期间的某个时刻Tc,系统把数据A=100转储到磁带上,而在下一时刻Td,某一事务将A改为200。转储结束后,后备副本上的A已是过时的数据了。
  为此,必须把转储期间各事务对数据库的修改活动登记下来,建立日志文件(log file)。这样,后援副本加上日志文件就能把数据库恢复到某一时刻的正确状态。
  转储还可以分为海量转储和增量转储两种方式。海量转储是指每次转储全部数据库。增量转储则指每次只转储上一次转储后更新过的数据。从恢复角度看,使用海量转储得到的后备副本进行恢复一般说来会更方便些。但如果数据库很大,事务处理又十分频繁,则增量转储方式更实用更有效。
  数据转储有两种方式,分别可以在两种状态下进行,因此数据转储方法可以分为四类:动态海量转储、动态增量转储、静态海量转储和静态增量转储。
  7.4.2 登记日志文件(Logging
  一、日志文件的格式和内容
  日志文件是用来记录事务对数据库的更新操作的文件。不同数据库系统采用的日志文件格式并不完全一样。概括起来日志文件主要有两种格式:以记录为单位的日志文件和以数据块为单位的日志文件。
  对于以记录为单位的日志文件,日志文件中需要登记的内容包括:
  · 各个事务的开始(BEGIN TRANSACTION)标记
  · 各个事务的结束(COMMITROLLBACK)标记
  · 各个事务的所有更新操作
  这里每个事务开始的标记、每个事务的结束标记和每个更新操作均作为日志文件中的一个日志记录(log record)
  每个日志记录的内容主要包括:
  · 事务标识(标明是哪个事务)
  · 操作的类型(插入、删除或修改)
  · 操作对象(记录内部标识)
  · 更新前数据的旧值(对插入操作而言,此项为空值)
  · 更新后数据的新值(对删除操作而言, 此项为空值)
  对于以数据块为单位的日志文件,日志记录的内容包括事务标识和被更新的数据块。由于将更新前的整个块和更新后的整个块都放入日志文件中,操作的类型和操作对象等信息就不必放入日志记录中。
  二、日志文件的作用
  日志文件在数据库恢复中起着非常重要的作用。可以用来进行事务故障恢复和系统故障恢复,并协助后备副本进行介质故障恢复。具体作用是:
  (1)事务故障恢复和系统故障必须用日志文件。
  (2)在动态转储方式中必须建立日志文件,后援副本和日志文件综合起来才能有效地恢复数据库。
  (3)在静态转储方式中,也可以建立日志文件。当数据库毁坏后可重新装入后援副本把数据库恢复到转储结束时刻的正确状态,然后利用日志文件,把已完成的事务进行重做处理,对故障发生时尚未完成的事务进行撤销处理。这样不必重新运行那些已完成的事务程序就可把数据库恢复到故障前某一时刻的正确状态。
  三、登记日志文件(Logging
  为保证数据库是可恢复的,登记日志文件时必须遵循两条原则:
  (1)登记的次序严格按并发事务执行的时间次序。
  (2)必须先写日志文件,后写数据库。
  
  把对数据的修改写到数据库中和把表示这个修改的日志记录写到日志文件中是两个不同的操作。有可能在这两个操作之间发生故障,即这两个写操作只完成了一个。如果先写了数据库修改,而在运行记录中没有登记这个修改,则以后就无法恢复这个修改了。如果先写日志,但没有修改数据库,按日志文件恢复时只不过是多执行一次不必要的UNDO操作,并不会影响数据库的正确性。所以为了安全,一定要先写日志文件,即首先把日志记录写到日志文件中,然后写数据库的修改。这就是"先写日志文件"的原则。

第七章 数据库恢复技术

第五节 恢复策略

  当系统运行过程中发生故障,利用数据库后备副本和日志文件就可以将数据库恢复到故障前的某个一致性状态。不同故障其恢复策略和方法也不一样。
  7.5.1 事务故障的恢复
  事务故障是指事务在运行至正常终止点前被终止,这时恢复子系统应利用日志文件撤销(UNDO)此事务已对数据库进行的修改。事务故障的恢复是由系统自动完成的,对用户是透明的。系统的恢复步骤是:
  (1)反向扫描文件日志(即从最后向前扫描日志文件),查找该事务的更新操作。
  (2)对该事务的更新操作执行逆操作。即将日志记录中"更新前的值"写入数据库。这样,如果记录中是插入操作,则相当于做删除操作(因此时"更新前的值"为空);若记录中是删除操作,则做插入操作;若是修改操作,则相当于用修改前值代替修改后值。
  (3)继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理。
  (4)如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了。
  7.5.2 系统故障的恢复
  前面已讲过,系统故障造成数据库不一致状态的原因有两个,一是未完成事务对数据库的更新可能已写入数据库,二是已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库。因此恢复操作就是要撤销故障发生时未完成的事务,重做已完成的事务。
  系统故障的恢复是由系统在重新启动时自动完成的,不需要用户干预。
  系统的恢复步骤是:
  (1)正向扫描日志文件(即从头扫描日志文件),找出在故障发生前已经提交的事务(这些事务既有BEGIN TRANSACTION记录,也有COMMIT记录),将其事务标识记入重做(REDO)队列。同时找出故障发生时尚未完成的事务(这些事务只有BEGIN TRANSACTION记录,无相应的COMMIT记录),将其事务标识记入撤销队列。
  (2)对撤销队列中的各个事务进行撤销(UNDO)处理。
  进行UNDO处理的方法是,反向扫描日志文件,对每个UNDO事务的更新操作执行逆操作,即将日志记录中"更新前的值"写入数据库。
  (3)对重做队列中的各个事务进行重做(REDO)处理。
  进行REDO处理的方法是:正向扫描日志文件,对每个REDO事务重新执行日志文件登记的操作。即将日志记录中"更新后的值"写入数据库。
  7.5.3 介质故障的恢复
  发生介质故障后,磁盘上的物理数据和日志文件被破坏,这是最严重的一种故障,恢复方法是重装数据库,然后重做已完成的事务。具体地说就是:
  1. 装入最新的数据库后备副本(离故障发生时刻最近的转储副本),使数据库恢复到最近一次转储时的一致性状态。
  对于动态转储的数据库副本,还需同时装入转储开始时刻的日志文件副本,利用恢复系统故障的方法(即REDO+UNDO),才能将数据库恢复到一致性状态。
  2. 装入相应的日志文件副本(转储结束时刻的日志文件副本),重做已完成的事务。即
  首先扫描日志文件,找出故障发生时已提交的事务的标识,将其记入重做队列。然后正向扫描日志文件,对重做队列中的所有事务进行重做处理。即将日志记录中"更新后的值"写入数据库。
  这样就可以将数据库恢复至故障前某一时刻的一致状态了。
  
  介质故障的恢复需要DBA介入。但DBA只需要重装最近转储的数据库副本和有关的各日志文件副本,然后执行系统提供的恢复命令即可,具体的恢复操作仍由DBMS完成。

第七章 数据库恢复技术

第六节 具有检查点的恢复技术

  利用日志技术进行数据库恢复时,恢复子系统必须搜索日志,确定哪些事务需要REDO,哪些事务需要UNDO。一般来说,需要检查所有日志记录。这样做具有两个问题。一是搜索整个日志将耗费大量的时间。二是很多需要REDO处理的事务实际上已经将它们的更新操作结果写到数据库中了,然而恢复子系统又重新执行了这些操作,浪费了大量时间。为了解决这些问题,又发展了具有检查点的恢复技术。这种技术在日志文件中增加一类新的记录检查点(checkpoint)记录,增加一个重新开始文件,并让恢复子系统在登录日志文件期间动态地维护日志。
  检查点记录的内容包括:
   建立检查点时刻所有正在执行的事务清单。
   这些事务最近一个日志记录的地址。
  重新开始文件用来记录各个检查点记录在日志文件中的地址。
  动态维护日志文件的方法是,周期性地执行如下操作:建立检查点,保存数据库状态。具体步骤是:
   将当前日志缓冲中的所有日志记录写入磁盘的日志文件上;
   在日志文件中写入一个检查点记录;
   将当前数据缓冲的所有数据记录写入磁盘的数据库中;
   把检查点记录在日志文件中的地址写入一个重新开始文件。
  恢复子系统可以定期或不定期地建立检查点保存数据库状态。检查点可以按照预定的一个时间间隔建立,如每隔一小时建立一个检查点;也可以按照某种规则建立检查点,如日志文件已写满一半建立一个检查点。
  使用检查点方法可以改善恢复效率。当事务T在一个检查点之前提交,T对数据库所做的修改一定都已写入数据库,写入时间是在这个检查点建立之前或在这个检查点建立之时。这样,在进行恢复处理时,没有必要对事务T执行REDO操作。
  系统出现故障时恢复子系统将根据事务的不同状态采取不同的恢复策略。

第七章 数据库恢复技术

第七节 数据库镜像

  根据前面所述,介质故障是对系统影响最为严重的一种故障。系统出现介质故障后,用户应用全部中断,恢复起来也比较费时。而且DBA必须周期性地转储数据库,这也加重了DBA的负担。如果不及时而正确地转储数据库,一旦发生介质故障,会造成较大的损失。
  随着磁盘容量越来越大,价格越来越便宜,为避免磁盘介质出现故障影响数据库的可用性,许多数据库管理系统提供了数据库镜像(Mirror)功能用于数据库恢复。即根据DBA的要求,自动把整个数据库或其中的关键数据复制到另一个磁盘上。每当主数据库更新时,DBMS自动把更新后的数据复制过去,即DBMS自动保证镜像数据与主数据的一致性(如图7.5(a)所示)。这样,一旦出现介质故障,可由镜像磁盘继续提供使用,同时DBMS自动利用镜像磁盘数据进行数据库的恢复,不需要关闭系统和重装数据库副本(如图7.5(b)所示)。在没有出现故障时,数据库镜像还可以用于并发操作,即当一个用户对数据加排它锁修改数据时,其他用户可以读镜像数据库上的数据,而不必等待该用户释放锁。
  由于数据库镜像是通过复制数据实现的,频繁地复制数据自然会降低系统运行效率,因此在实际应用中用户往往只选择对关键数据和日志文件镜像,而不是对整个数据库进行镜像。

第七章 数据库恢复技术

第八节 Oracle的恢复技术

  上面介绍了恢复技术的一般原理,实际DBMS产品中的恢复策略往往都有自己的特色。下面简单介绍一下Oracle的恢复技术,以加深对数据库恢复技术的理解。
  Oracle中恢复机制也采用了转储和登记日志文件两个技术。
  OracleDBA提供了多种转储后备副本的方法,如文件拷贝、利用OracleExport实用程序、用SQL命令Spool以及自己编程实现等。相应地,Oracle也提供了多种重装后备副本的方法,如文件拷贝、利用OracleImport实用程序、利用SQL*LOADER以及自己编程实现等。
  在Oracle 早期版本(V.5)中,日志文件以数据块为单位,也就是说,Oracle的恢复操作不是基于操作,而是基于数据块的。Oracle将更新前的旧值与更新后的新值分别放在两个不同的日志文件中。记录数据库更新前的旧值的日志文件称为数据库前像文件(Before Image,简称BI文件),记录数据库更新后的新值的日志文件称为数据库的后像文件(After Image,简称AI文件)。由于BI文件关系到能否将数据库恢复到一致性状态,因此BI文件是必须的。而AI文件的作用是减少必须重新运行的事务程序,尽可能多地恢复数据库,所以在OracleAI文件是任选的。日志文件是十分占据空间的,为节省存储空间和操作时间,DBA可以不配置AI文件。没有AI文件,恢复机制进行故障恢复时只能执行UNDO处理,不能执行REDO处理。
  
  Oracle7为了能够在出现故障时更有效地恢复数据,也为了解决读""数据问题(参阅第八章),提供了REDO日志文件和回滚段(Rollback Segment)。REDO日志文件中记录了被更新数据的前像和后像,设在数据库缓冲区中的回滚段记录更新数据的前像。在利用日志文件进行故障恢复时,为减少扫描日志文件的遍数,Oracle7首先扫描REDO日志文件,重做所有操作,包括未正常提交的事务的操作,然后再根据回滚段中的数据,撤销未正常提交的事务的操作
  。

第七章 数据库恢复技术

第九节 小结

  保证数据一致性是对数据库的最基本的要求。事务是数据库的逻辑工作单位,只要DBMS能够保证系统中一切事务的原子性、一致性、隔离性和持续性,也就保证了数据库处于一致状态。为了保证事务的原子性、一致性与持续性,DBMS必须对事务故障、系统故障和介质故障进行恢复。数据库转储和登记日志文件是恢复中最经常使用的技术。恢复的基本原理就是利用存储在后备副本、日志文件和数据库镜像中的冗余数据来重建数据库。
  事务不仅是恢复的基本单位,也是并发控制的基本单位,为了保证事务的隔离性,保证事务的一致性,DBMS需要对并发操作进行控制。

第八章 并发控制

第一节 并发控制概述

  数据库是一个共享资源,可以供多个用户使用。允许多个用户同时使用的数据库系统称为多用户数据库系统。例如飞机定票数据库系统、银行数据库系统等都是多用户数据库系统。在这样的系统中,在同一时刻并行运行的事务数可达数百个。
  事务可以一个一个地串行执行,即每个时刻只有一个事务运行,其他事务必须等到这个事务结束以后方能运行。事务在执行过程中需要不同的资源,有时需要CPU,有时需要存取数据库,有时需要I/O,有时需要通信。如果事务串行执行,则许多系统资源将处于空闲状态。因此,为了充分利用系统资源发挥数据库共享资源的特点,应该允许多个事务并行地执行。
  在单处理机系统中,事务的并行执行实际上是这些并行事务的并行操作轮流交叉运行。这种并行执行方式称为交叉并发方式(Interleaved Concurrency)。虽然单处理机系统中的并行事务并没有真正地并行运行,但是减少了处理机的空闲时间,提高了系统的效率。
  在多处理机系统中,每个处理机可以运行一个事务,多个处理机可以同时运行多个事务,实现多个事务真正的并行运行。这种并行执行方式称为同时并发方式(Simultaneous Concurrency)。本章讨论的数据库系统并发控制技术是以单处理机系统为基础的。这些理论可以推广到多处理机的情况。
  
  当多个用户并发地存取数据库时就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会存取和存储不正确的数据,破坏数据库的一致性。所以数据库管理系统必须提供并发控制机制。并发控制机制是衡量一个数据库管理系统性能的重要标志之一。
  
  在第七章中已经讲到,事务是并发控制的基本单位,保证事务ACID特性是事务处理的重要任务,而事务ACID特性可能遭到破坏的原因之一是多个事务对数据库的并发操作造成的。为了保证事务的隔离性更一般,为了保证数据库的一致性,DBMS需要对并发操作进行正确调度。这些就是数据库管理系统中并发控制机制的责任。
  仔细分析并发操作带来的数据不一致性包括三类:丢失修改、不可重复读和读""数据。
  产生上述三类数据不一致性的主要原因是并发操作破坏了事务的隔离性。并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性。
  另一方面,对数据库的应用有时允许某些不一致性,例如有些统计工作涉及数据量很大,读到一些""数据对统计精度没什么影响,这时可以降低对一致性的要求以减少系统开销。
  
  并发控制的主要技术是封锁(Locking)。

第八章 并发控制

第二节 封锁

  封锁是实现并发控制的一个非常重要的技术。所谓封锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。
  确切的控制由封锁的类型决定。基本的封锁类型有两种: 排它锁(Exclusive Locks,简称X) 和共享锁(Share Locks,简称S).
  排它锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A
  共享锁又称为读锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对AS锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

第八章 并发控制

第三节 封锁协议

  在运用X锁和S锁这两种基本封锁,对数据对象加锁时,还需要约定一些规则,例如何时申请X锁或S锁、持锁时间、何时释放等。称这些规则为封锁协议(Locking Protocol)。对封锁方式规定不同的规则,就形成了各种不同的封锁协议。下面介绍三级封锁协议。对并发操作的不正确调度可能会带来丢失修改、不可重复读和读""数据等不一致性问题,三级封锁协议分别在不同程度上解决了这一问题。为并发操作的正确调度提供一定的保证。不同级别的封锁协议达到的系统一致性级别是不同的。
  一、一级封锁协议
  一级封锁协议是:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。
  一级封锁协议可防止丢失修改,并保证事务T是可恢复的。
  在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不读""数据。
  二、二级封锁协议
  二级封锁协议是:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后即可释放S锁。
  二级封锁协议除防止了丢失修改,还可进一步防止读""数据。
  在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读。
  三、三级封锁协议
  三级封锁协议是:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。
  三级封锁协议除防止了丢失修改和不读""数据外,还进一步防止了不可重复读。
  上述三级协议的主要区别在于什么操作需要申请封锁,以及何时释放锁(即持锁时间)

第八章 并发控制

第四节 活锁和死锁

  和操作系统一样,封锁的方法可能引起活锁和死锁。
  一、活锁
  如果事务T1封锁了数据R,事务T2又请求封锁R,于是T2等待。T3也请求封锁R,当T1释放了R上的封锁之后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了R上的封锁之后系统又批准了T4的请求……T2有可能永远等待,这就是活锁的情形,避免活锁的简单方法是采用先来先服务的策略。当多个事务请求封锁同一数据对象时,封锁子系统按请求封锁的先后次序对事务排队,数据对象上的锁一旦释放就批准申请队列中第一个事务获得锁。
  二、死锁
  
  如果事务T1封锁了数据R1T2封锁了数据R2,然后T1又请求封锁R2,因T2已封锁了R2,于是T1等待T2释放R2上的锁。接着T2又申请封锁R1,因T1已封锁了R1T2也只能等待T1释放R1上的锁。这样就出现了T1在等待T2,而T2又在等待T1的局面,T1T2两个事务永远不能结束,形成死锁。如图8.4(b)所示。
  死锁的问题在操作系统和一般并行处理中已做了深入研究,目前在数据库中解决死锁问题主要有两类方法,一类方法是采取一定措施来预防死锁的发生,另一类方法是允许发生死锁,采用一定手段定期诊断系统中有无死锁,若有则解除之。
  1. 死锁的预防
  在数据库中,产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求对已为其他事务封锁的数据对象加锁,从而出现死等待。防止死锁的发生其实就是要破坏产生死锁的条件。预防死锁通常有两种方法:
  (1)一次封锁法
  一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。如图8.4(b)的例子中,如果事务T1将数据对象R1R2一次加锁,T1就可以执行下去,而T2等待。T1执行完后释放R1R2上的锁,T2继续执行。这样就不会发生死锁。
  一次封锁法虽然可以有效地防止死锁的发生,但也存在问题。第一,一次就将以后要用到的全部数据加锁,势必扩大了封锁的范围,从而降低了系统的并发度。第二,数据库中数据是不断变化的,原来不要求封锁的数据,在执行过程中可能会变成封锁对象,所以很难事先精确地确定每个事务所要封锁的数据对象,为此只能扩大封锁范围,将事务在执行过程中可能要封锁的数据对象全部加锁,这就进一步降低了并发度。
  (2)顺序封锁法
  顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。例如在B树结构的索引中,可规定封锁的顺序必须是从根结点开始,然后是下一级的子女结点,逐级封锁。
  顺序封锁法可以有效地防止死锁,但也同样存在问题。第一,数据库系统中封锁的数据对象极多,并且随数据的插入、删除等操作而不断地变化,要维护这样的资源的封锁顺序非常困难,成本很高。第二,事务的封锁请求可以随着事务的执行而动态地决定,很难事先确定每一个事务要封锁哪些对象,因此也就很难按规定的顺序去施加封锁。
  可见,在操作系统中广为采用的预防死锁的策略并不很适合数据库的特点,因此DBMS在解决死锁的问题上普遍采用的是诊断并解除死锁的方法。
  2. 死锁的诊断与解除
  数据库系统中诊断死锁的方法与操作系统类似,一般使用超时法或事务等待图法。
  (1)超时法
  如果一个事务的等待时间超过了规定的时限,就认为发生了死锁。超时法实现简单,但其不足也很明显。一是有可能误判死锁,事务因为其他原因使等待时间超过时限,系统会误认为发生了死锁。二是时限若设置得太长,死锁发生后不能及时发现。
  (2)等待图法
  事务等待图是一个有向图G=(TU)T为结点的集合,每个结点表示正运行的事务;U为边的集合,每条边表示事务等待的情况。若T1等待T2,则T1T2之间划一条有向边,从T1指向T2。事务等待图动态地反映了所有事务的等待情况。并发控制子系统周期性地(比如每隔1 min)检测事务等待图,如果发现图中存在回路,则表示系统中出现了死锁。
  
  DBMS的并发控制子系统一旦检测到系统中存在死锁,就要设法解除。通常采用的方法是选择一个处理死锁代价最小的事务,将其撤消,释放此事务持有的所有的锁,使其他事务得以继续运行下去。当然,对撤销的事务所执行的数据修改操作必须加以恢复。

第八章 并发控制

第五节 并发调度的可串行性

  计算机系统对并发事务中并发操作的调度是随机的,而不同的调度可能会产生不同的结果,那么哪个结果是正确的,哪个是不正确的呢?
  如果一个事务运行过程中没有其他事务同时运行,也就是说它没有受到其他事务的干扰,那么就可以认为该事务的运行结果是正常的或者预想的。因此将所有事务串行起来的调度策略一定是正确的调度策略。虽然以不同的顺序串行执行事务可能会产生不同的结果,但由于不会将数据库置于不一致状态,所以都是正确的。
  定义 多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同,我们称这种调度策略为可串行化(Serializable)的调度。
  可串行性(Serializability)是并发事务正确性的准则。按这个准则规定,一个给定的并发调度,当且仅当它是可串行化的,才认为是正确调度。
  为了保证并发操作的正确性,DBMS的并发控制机制必须提供一定的手段来保证调度是可串行化的。
  从理论上讲,在某一事务执行时禁止其他事务执行的调度策略一定是可串行化的调度,这也是最简单的调度策略,但这种方法实际上是不可取的,这使用户不能充分共享数据库资源。目前DBMS普遍采用封锁方法实现并发操作调度的可串行性,从而保证调度的正确性。
  两段锁(Two-Phase Locking,简称2PL)协议就是保证并发调度可串行性的封锁协议。
  除此之外还有其他一些方法,如时标方法、乐观方法等来保证调度的正确性。

第八章 并发控制

第六节 两段锁协议

  所谓两段锁协议是指所有事务必须分两个阶段对数据项加锁和解锁。
  · 在对任何数据进行读、写操作之前,首先要申请并获得对该数据的封锁;
  · 在释放一个封锁之后,事务不再申请和获得任何其他封锁。
  
  所谓"两段"锁的含义是,事务分为两个阶段,第一阶段是获得封锁,也称为扩展阶段。在这阶段,事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁。第二阶段是释放封锁,也称为收缩阶段。在这阶段,事务可以释放任何数据项上的任何类型的琐,但是不能再申请任何琐。
  需要说明的是,事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件。也就是说,若并发事务都遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的;若对并发事务的一个调度是可串行化的,不一定所有事务都符合两段锁协议。
  另外要注意两段锁协议和防止死锁的一次封锁法的异同之处。一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行,因此一次封锁法遵守两段锁协议;但是两段锁协议并不要求事务必须一次将所有要使用的数据全部加锁,因此遵守两段锁协议的事务可能发生死锁。

第八章 并发控制

第七节 封锁的粒度

  封锁对象的大小称为封锁粒度(Granularity)。封锁对象可以是逻辑单元,也可以是物理单元。以关系数据库为例,封锁对象可以是这样一些逻辑单元: 属性值、属性值的集合、元组、关系、索引项、整个索引直至整个数据库;也可以是这样一些物理单元:(数据页或索引页)、块等。
  封锁粒度与系统的并发度和并发控制的开销密切相关。直观地看,封锁的粒度越大,数据库所能够封锁的数据单元就越少,并发度就越小,系统开销也越小;反之,封锁的粒度越小,并发度较高,但系统开销也就越大。
  例如,若封锁粒度是数据页,事务T1需要修改元组L1,则T1必须对包含L1的整个数据页A加锁。如果T1A加锁后事务T2要修改A中元组L2,则T2被迫等待,直到T1释放A。如果封锁粒度是元组,则T1T2可以同时对L1L2加锁,不需要互相等待,提高了系统的并行度。又如,事务T需要读取整个表,若封锁粒度是元组,T必须对表中的每一个元组加锁,显然开销极大。
  
  因此, 如果在一个系统中同时支持多种封锁粒度供不同的事务选择是比较理想的,这种封锁方法称为多粒度封锁(Multiple Granularity Locking)。选择封锁粒度时应该同时考虑封锁开销和并发度两个因素,适当选择封锁粒度以求得最优的效果。一般说来,需要处理大量元组的事务可以以关系为封锁粒度;需要处理多个关系的大量元组的事务可以以数据库为封锁粒度;而对于一个处理少量元组的用户事务,以元组为封锁粒度就比较合适了。
  8.7.1 多粒度封锁
  8.7.2 意向锁
  下面介绍三种常用的意向锁:意向共享锁(Intent Share Lock,简称IS);意向排它锁(Intent Exclusive Lock,简称IX);共享意向排它锁(Share Intent Exclusive Lock,简称SIX)
  1. IS
  如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。例如,要对某个元组加S锁,则要首先对关系和数据库加IS
  2. IX
  如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。例如,要对某个元组加X锁,则要首先对关系和数据库加IX锁。
  3. SIX
  如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁,即SIX = S + IX。例如对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别元组(所以要对该表加IX锁)。

第八章 并发控制

第八节 Oracle的并发控制

  前面讨论了并发控制的一般原则与方法,下面简单介绍Oracle数据库系统中的并发控制机制。
  Oracle采用封锁技术保证并发操作的可串行性。Oracle的锁分为两大类:数据锁(亦称DML锁)和字典锁。字典锁是ORACLE DBMS内部用于对字典表的封锁。字典锁包括语法分析锁和DDL锁,由DBMS在必要的时候自动加锁和释放锁,用户无权控制。
  Oracle主要提供了5种数据锁:共享锁(S锁)、排它锁(X锁)、行级共享锁(RS锁)、行级排它锁(RX锁)和共享行级排它锁(SRX锁)。其封锁粒度包括行级和表级。
  Oracle RS锁、RX锁、SRX锁实际上就是上面介绍的IS锁、IX锁、SIX锁。
  在通常情况下,数据封锁由系统控制,对用户是透明的。但Oracle也允许用户用LOCK TABLE语句显式对封锁对象加锁。
  Oracle数据锁的一个显著特点是,在缺省情况下,读数据不加锁。也就是说,当一个用户更新数据时,另一个用户可以同时读取相应数据,反之亦然。Oracle通过回滚段(Rollback Segment)的内存结构来保证用户不读""数据和可重复读。这样做的好处是提高了数据的并发度。
  Oracle提供了有效的死锁检测机制,周期性诊断系统中有无死锁,若存在死锁,则撤销执行更新操作次数最少的事务。

第八章 并发控制

第九节 小结

  数据库的重要特征是它能为多个用户提供数据共享。数据库管理系统允许共享的用户数目是数据库管理系统重要标志之一。数据库管理系统必须提供并发控制机制来协调并发用户的并发操作以保证并发事务的隔离性,保证数据库的一致性。
  数据库的并发控制以事务为单位,通常使用封锁技术实现并发控制。本章介绍了两类最常用的封锁和三级封锁协议。不同的封锁和不同级别的封锁协议所提供的系统一致性保证是不同的,提供数据共享度也是不同的。
  并发控制机制调度并发事务操作是否正确的判别准则是可串行性,两段锁协议是可串行化调度的充分条件,但不是必要条件。因此,两段锁协议可以保证并发事务调度的正确性。
  对数据对象施加封锁,会带来活锁和死锁问题,并发控制机制必须提供适合数据库特点的解决方法。
  不同的数据库管理系统提供的封锁类型、封锁协议、达到的系统一致性级别不尽相同。但是其依据的基本原理和技术是共同的。

第九章 数据库安全性

第一节 计算机安全性概论

  数据库的安全性是指保护数据库以防止不合法的使用所造成的数据泄露、更改或破坏。
  安全性问题不是数据库系统所独有的,所有计算机系统都有这个问题。只是在数据库系统中大量数据集中存放,而且为许多最终用户直接共享,从而使安全性问题更为突出。系统安全保护措施是否有效是数据库系统的主要指标之一。
  数据库的安全性和计算机系统的安全性,包括操作系统、网络系统的安全性是紧密联系、相互支持的,因此在讨论数据库的安全性之前首先讨论计算机系统安全性的一般问题。
  9.1.1 计算机系统的三类安全性问题
  所谓计算机系统安全性,是指为计算机系统建立和采取的各种安全保护措施,以保护计算机系统中的硬件、软件及数据,防止其因偶然或恶意的原因使系统遭到破坏,数据遭到更改或泄露等。计算机安全不仅涉及到计算机系统本身的技术问题、管理问题,还涉及法学、犯罪学、心理学的问题。其内容包括了计算机安全理论与策略;计算机安全技术、安全管理、安全评价、安全产品以及计算机犯罪与侦察、计算机安全法律、安全监察等。概括起来,计算机系统的安全性问题可分为三大类,即技术安全类、管理安全类和政策法律类。
  
  技术安全是指计算机系统中采用具有一定安全性的硬件、软件来实现对计算机系统及其所存数据的安全保护,当计算机系统受到无意或恶意的攻击时仍能保证系统正常运行,保证系统内的数据不增加、不丢失、不泄露。技术安全之外的,诸如软硬件意外故障、场地的意外事故、管理不善导致的计算机设备和数据介质的物理破坏、丢失等安全问题,视为管理安全。而政策法律类则指政府部门建立的有关计算机犯罪、数据安全保密的法律道德准则和政策法规、法令,本书只讨论技术安全类。
   随着计算机资源共享和网络技术的应用日益广泛和深入,特别是Internet技术的发展,计算机安全性问题越来越得到人们的重视。对各种计算机及其相关产品、信息系统的安全性要求越来越高。为此,在计算机安全技术方面逐步发展建立了一套可信(Trusted)计算机系统的概念和标准。只有建立了完善的可信或安全标准,才能规范和指导安全计算机系统部件的生产,比较准确地测定产品的安全性能指标,满足民用和国防的需要。
  9.1.2 可信计算机系统评测标准
  为降低进而消除对系统的安全攻击,尤其是弥补原有系统在安全保护方面的缺陷,在计算机安全技术方面逐步建立了一套可信标准。在目前各国所引用或制定的一系列安全标准中,最重要的当推1985年美国国防部(DoD)正式颁布的《 DoD可信计算机系统评估标准》
  制定这个标准的目的主要有:
  (1)提供一种标准,使用户可以对其计算机系统内敏感信息安全操作的可信程度做评估。
  (2)给计算机行业的制造商提供一种可循的指导规则,使其产品能够更好地满足敏感应用的安全需求。
  TCSEC又称桔皮书,19914月美国NCSC(国家计算机安全中心)颁布了《可信计算机系统评估标准关于可信数据库系统的解释》( Trusted Database Interpretation 简称TDI,即紫皮书)。将TCSEC扩展到数据库管理系统。TDI中定义了数据库管理系统的设计与实现中需满足和用以进行安全性级别评估的标准。
  以下着重介绍TDI/TCSEC标准的基本内容。
  TDITCSEC一样,从以下四个方面来描述安全性级别划分的指标:安全策略、责任、保证和文档。每个方面又细分为若干项。
  根据计算机系统对上述各项指标的支持情况,TCSECTDI)将系统划分为四组(division)七个等级,依次是DCC1C2);BB1B2B3);AA1),按系统可靠或可信程度逐渐增高,如表9.1所示。
  在TCSEC中建立的安全级别之间具有一种偏序向下兼容的关系,即较高安全性级别提供的安全保护要包含较低级别的所有保护要求,同时提供更多或更完善的保护能力。
  下面,简略地对各个等级作一介绍。
  D D级是最低级别。保留D级的目的是为了将一切不符合更高标准的系统,统统归于D组。如DOS就是操作系统中安全标准为D的典型例子。它具有操作系统的基本功能,如文件系统,进程调度等,但在安全性方面几乎没有什么专门的机制来保障。
  C1 只提供了非常初级的自主安全保护。能够实现对用户和数据的分离,进行自主存取控制(DAC),保护或限制用户权限的传播。现有的商业系统往往稍作改进即可满足要求。
  C2 实际是安全产品的最低档次,提供受控的存取保护,即将C1级的DAC进一步细化,以个人身份注册负责,并实施审计和资源隔离。很多商业产品已得到该级别的认证。达到C2级的产品在其名称中往往不突出"安全"(Security)这一特色,如操作系统中MicrosoftWindows NT 3.5,数字设备公司的Open VMS VAX 6.06.1。数据库产品有Oracle公司的Oracle 7Sybase公司的 SQL Server 11.0.6 等。
  B1 标记安全保护。对系统的数据加以标记,并对标记的主体和客体实施强制存取控制(MAC)以及审计等安全机制。B1级能够较好地满足大型企业或一般政府部门对于数据的安全需求,这一级别的产品才认为是真正意义上的安全产品。满足此级别的产品前一般多冠以"安全"(Security)"可信的"(Trusted)字样,作为区别于普通产品的安全产品出售。
  B2 结构化保护。建立形式化的安全策略模型并对系统内的所有主体和客体实施DACMAC
  从互联网上的最新资料看,经过认证的、B2级以上的安全系统非常稀少。例如,符合B2标准的操作系统只有Trusted Information Systems公司的Trusted XENIX一种产品,符合B2标准的网络产品只有Cryptek Secure Communications公司的LLC VSLAN一种产品,而数据库方面则没有符合B2标准的产品。
  B3 安全域。该级的TCB必须满足访问监控器的要求,审计跟踪能力更强,并提供系统恢复过程。
  A1 验证设计,即提供B3级保护的同时给出系统的形式化设计说明和验证以确信各安全保护真正实现。

第九章 数据库安全性

第二节 数据库安全性控制

  安全模型中,用户要求进入计算机系统时,系统首先根据输入的用户标识进行用户身份鉴定,只有合法的用户才准许进入计算机系统。对已进入系统的用户,DBMS还要进行存取控制,只允许用户执行合法操作。操作系统一级也会有自己的保护措施。数据最后还可以以密码形式存储到数据库中。操作系统一级的安全保护措施可参考操作系统的有关书籍,这里不再详叙。另外对于强力逼迫透露口令、盗窃物理存储设备等行为而采取的保安措施,例如出入机房登记、加锁等,也不在这里讨论之列。
  这里只讨论与数据库有关的用户标识和鉴定、存取控制、视图和密码存储等安全技术。
  9.2.1 用户标识与鉴别
  用户标识和鉴别是系统提供的最外层安全保护措施。其方法是由系统提供一定的方式让用户标识自己的名字或身份。每次用户要求进入系统时,由系统进行核对,通过鉴定后才提供机器使用权。
  对于获得上机权的用户若要使用数据库时数据库管理系统还要进行用户标识和鉴定。
  
  用户标识和鉴定的方法有很多种,而且在一个系统中往往是多种方法并举,以获得更强的安全性。常用的方法有:
  用一个用户名或者用户标识号来标明用户身份。系统内部记录着所有合法用户的标识,系统鉴别此用户是否是合法用户,若是,则可以进入下一步的核实;若不是,则不能使用系统。
  口令(Password 为了进一步核实用户,系统常常要求用户输入口令。为保密起见,用户在终端上输入的口令不显示在屏幕上。系统核对口令以鉴别用户身份。
  通过用户名和口令来鉴定用户的方法简单易行,但用户名与口令容易被人窃取,因此还可以用更复杂的方法。例如每个用户都预先约定好一个计算过程或者函数,鉴别用户身份时,系统提供一个随机数,用户根据自己预先约定的计算过程或者函数进行计算,系统根据用户计算结果是否正确进一步鉴定用户身份。用户可以约定比较简单的计算过程或函数,以便计算起来方便;也可以约定比较复杂的计算过程或函数,以便安全性更好。
  用户标识和鉴定可以重复多次。
  9.2.2 存取控制
  数据库安全性所关心的主要是DBMS的存取控制机制。数据库安全最重要的一点就是确保只授权给有资格的用户访问数据库的权限,同时令所有未被授权的人员无法接近数据,这主要通过数据库系统的存取控制机制实现。
  存取控制机制主要包括两部分:
  1. 定义用户权限,并将用户权限登记到数据字典中。用户权限是指不同的用户对于不同的数据对象允许执行的操作权限。系统必须提供适当的语言定义用户权限,这些定义经过编译后存放在数据字典中,被称作安全规则或授权规则。
  2. 合法权限检查,每当用户发出存取数据库的操作请求后(请求一般应包括操作类型、操作对象和操作用户等信息),DBMS查找数据字典,根据安全规则进行合法权限检查,若用户的操作请求超出了定义的权限,系统将拒绝执行此操作。
  用户权限定义和合法权检查机制一起组成了DBMS的安全子系统。
  前面已经讲到,当前大型的DBMS一般都支持C2级中的自主存取控制(DAC),有些DBMS同时还支持B1级中的强制存取控制(MAC)。
  这两类方法的简单定义是:
  (1)在自主存取控制方法中,用户对于不同的数据对象有不同的存取权限,不同的用户对同一对象也有不同的权限,而且用户还可将其拥有的存取权限转授给其他用户。因此自主存取控制非常灵活。
  (2)在强制存取控制方法中,每一个数据对象被标以一定的密级,每一个用户也被授予某一个级别的许可证。对于任意一个对象,只有具有合法许可证的用户才可以存取。强制存取控制因此相对比较严格。
  下面介绍这两种存取控制方法
  9.2.3 自主存取控制(DAC)方法
  大型数据库管理系统几乎都支持自主存取控制,目前的SQL标准也对自主存取控制提供支持,这主要通过 SQL GRANT 语句和 REVOKE 语句来实现。
  用户权限是由两个要素组成的:数据对象和操作类型。定义一个用户的存取权限就是要定义这个用户可以在哪些数据对象上进行哪些类型的操作。在数据库系统中,定义存取权限称为授权(Authorization)。
  在非关系系统中,用户只能对数据进行操作,存取控制的数据对象也仅限于数据本身。而关系数据库系统中,DBA可以把建立、修改基本表的权限授予用户,用户获得此权限后可以建立和修改基本表、索引、视图。因此,关系系统中存取控制的数据对象不仅有数据本身,如表、属性列等,还有模式、外模式、内模式等数据字典中的内容。
  9.2.4 强制存取控制(MAC)方法
  所谓MAC是指系统为保证更高程度的安全性,按照TDI TCSEC标准中安全策略的要求,所采取的强制存取检查手段。它不是用户能直接感知或进行控制的。MAC适用于那些对数据有严格而固定密级分类的部门,例如军事部门或政府部门。
  9.2.5 视图机制
  进行存取权限控制时可以为不同的用户定义不同的视图,把数据对象限制在一定的范围内,也就是说,通过视图机制把要保密的数据对无权存取的用户隐藏起来,从而自动地对数据提供一定程度的安全保护。
  9.2.6 审计(Audit
  前面讲的用户标识与鉴别、存取控制仅是安全性标准的一个重要方面(安全策略方面)不是全部。为了使DBMS达到一定的安全级别,还需要在其他方面提供相应的支持。例如按照TDI TCSEC标准中安全策略的要求,"审计"功能就是DBMS达到C2以上安全级别必不可少的一项指标。
  因为任何系统的安全保护措施都不是完美无缺的,蓄意盗窃、破坏数据的人总是想方设法打破控制。审计功能把用户对数据库的所有操作自动记录下来放入审计日志(Audit Log)中。DBA可以利用审计跟踪的信息,重现导致数据库现有状况的一系列事件,找出非法存取数据的人、时间和内容等。
  审计通常是很费时间和空间的,所以DBMS往往都将其作为可选特征,允许DBA根据应用对安全性的要求,灵活地打开或关闭审计功能。审计功能一般主要用于安全性要求较高的部门。
  9.2.7 数据加密
  对于高度敏感性数据,例如财务数据、军事数据、国家机密,除以上安全性措施外,还可以采用数据加密技术。
  数据加密是防止数据库中数据在存储和传输中失密的有效手段。加密的基本思想是根据一定的算法将原始数据(术语为明文,Plain text)变换为不可直接识别的格式(术语为密文,Cipher text),从而使得不知道解密算法的人无法获知数据的内容。
  
  加密方法主要有两种,一种是替换方法,该方法使用密钥(Encryption Key)将明文中的每一个字符转换为密文中的一个字符。另一种是置换方法,该方法仅将明文的字符按不同的顺序重新排列。单独使用这两种方法的任意一种都是不够安全的。但是将这两种方法结合起来就能提供相当高的安全程度。采用这种结合算法的例子是美国1977年制定的官方加密标准,数据加密标准(Data Encryption Standard,简称DES)。
  有关DES密钥加密技术及密钥管理问题等已超出本书范围,这里不再讨论。
  目前有些数据库产品提供了数据加密例行程序,可根据用户的要求自动对存储和传输的数据进行加密处理。另一些数据库产品虽然本身未提供加密程序,但提供了接口,允许用户用其他厂商的加密程序对数据加密。
  由于数据加密与解密也是比较费时的操作,而且数据加密与解密程序会占用大量系统资源,因此数据加密功能通常也作为可选特征,允许用户自由选择,只对高度机密的数据加密。

第九章 数据库安全性

第三节 统计数据库安全性

  一般地,统计数据库允许用户查询聚集类型的信息(例如合计、平均值等),但是不允许查询单个记录信息。例如,查询"程序员的平均工资是多少?"是合法的,但是查询"程序员张勇的工资是多少?"就不允许。
  在统计数据库中存在着特殊的安全性问题,即可能存在着隐蔽的信息通道,使得可以从合法的查询中推导出不合法的信息。例如下面两个查询都是合法的:
  · 本公司共有多少女高级程序员?
  · 本公司女高级程序员的工资总额是多少?
  如果第1个查询的结果是"1",那么第2个查询的结果显然就是这个程序员的工资数。这样统计数据库的安全性机制就失效了。为了解决这个问题,可以规定任何查询至少要涉及N个以上的记录(N足够大)。但是即使这样,还是存在另外的泄密途径,看下面的例子:
  某个用户A想知道另一用户B的工资数额,他可以通过下列两个合法查询获取:
  · 用户A和其他N个程序员的工资总额是多少?
  · 用户B和其他N个程序员的工资总额是多少?
  假设第一个查询的结果是X,第二个查询的结果是Y,由于用户A知道自己的工资是Z,那么他可以计算出用户B的工资=Y-(X-Z)
  这个例子的关键之处在于两个查询之间有很多重复的数据项(即其他N个程序员的工资)。因此可以再规定任意两个查询的相交数据项不能超过M个。这样就使得获取他人的数据更加困难了。可以证明,在上述两条规定下,如果想获知用户B的工资额,用户A至少需要进行1+(N-2)/M次查询。
  当然可以继续规定任一用户的查询次数不能超过1+(N-2)/M,但是如果两个用户合作查询就可以使这一规定仍然失效。
  另外还有其他一些方法用于解决统计数据库的安全性问题,例如数据污染。但是无论采用什么安全性机制,都仍然会存在绕过这些机制的途径。好的安全性措施应该使得那些试图破坏安全的人所花费的代价远远超过他们所得到的利益,这也是整个数据库安全机制设计的目标。

第九章 数据库安全性

第四节 Oracle数据库的安全性措施

  下面介绍Oracle的安全性措施,使读者能进一步理解前面讨论的数据库安全性的基本方法。
  Oracle的安全措施主要有三个方面,一是用户标识和鉴定;二是授权和检查机制;三是审计技术(是否使用审计技术可由用户灵活选择);除此之外,Oracle还允许用户通过触发器灵活定义自己的安全性措施。
  一、用户标识和鉴定
  在Oracle中,最外层的安全性措施是让用户标识自己的名字,然后由系统进行核实。Oracle允许用户重复标识三次,如果三次未通过,系统自动退出。
  二、授权与检查机制
  Oracle的授权和检查机制与前面讲的存取控制方法基本相同。
  Oracle的权限包括系统权限和数据库对象的权限两类,采用非集中的授权机制,即DBA负责授予与回收系统权限,每个用户授予与回收自己创建的数据库对象的权限。
  Oracle允许重复授权,即可将某一权限多次授予同一用户,系统不会出错。Oracle也允许无效回收,即用户没有某种权限,但回收此权限的操作仍算成功。
  1. 系统权限
  Oracle提供了80多种系统权限,如创建会话、创建表、创建视图、创建用户等。DBA在创建一个用户时需要将其中的一些权限授予该用户。
  
  Oracle支持角色的概念。所谓角色就是一组系统权限的集合,目的在于减化权限管理。Oracle除允许DBA定义角色外,还提供了预定义的角色,如CONNECTRESOURCEDBA
  具有CONNECT角色的用户可以登录数据库,执行数据查询和操纵。即可以执行ALTER TABLECREATE VIEWCREATE INDEXDROP TABLEDROP VIEWDROP INDEXGRANTREVOKEINSERTSELECTUPDATEDELETEAUDITNOAUDIT等操作。
  RESOURCE角色可以创建表,即执行CREATE TABLE操作。创建表的用户将拥有对该表的所有权限。
  DBA角色可以执行某些授权命令,创建表,对任何表的数据进行操纵。它涵盖了前两种角色,此外还可以执行一些管理操作,DBA角色拥有最高级别的权限。
  例如DBA建立一用户U1后,欲将ALTER TABLECREATE VIEWCREATE INDEXDROP TABLEDROP VIEWDROP INDEXGRANTREVOKEINSERT SELECTUPDATEDELETEAUDITNOAUDIT等系统权限授予U1,则可以只简单地将CONNECT角色授予U1即可:
  GRANT CONNECT TO U1
  这样就可以省略十几条GRANT语句。
  2. 数据库对象的权限
  在Oracle中,可以授权的数据库对象包括基本表、视图、序列、同义词、存储过程、函数等,其中最重要的是基本表。
  对于基本表Oracle支持三个级别的安全性:表级、行级和列级。
  (1)表级安全性
  表的创建者或DBA可以把表级权限授予其他用户,表级权限包括:
   ALTER:修改表定义
   DELETE:删除表记录
   INDEX:在表上建索引
   INSERT:向表中插入数据记录
   SELECT:查找表中记录
   UPDATE:修改表中的数据
   ALL:上述所有权限
  表级授权使用GRANTREVOKE语句,其语法与第三章中介绍的基本一致。
  (2)行级安全性
  Oracle行级安全性由视图实现。用视图定义表的水平子集,限定用户在视图上的操作,就为表的行级提供了保护。视图上的授权与回收与表级完全相同。
  例如,只允许用户U2查看Student表中信息系学生的数据,则首先创建信息系学生视图S_IS,然后将该视图的SELECT权限授予U2用户。
  (3)列级安全性
  Oracle列级安全性可以由视图实现,也可以直接在基本表上定义。
  用视图定义表的垂直子集就可以实现列级安全性,方法与上面类似。
  直接在基本表上定义和回收列级权限也是使用GRANTREVOKE语句。目前Oracle的列级权限只有UPDATE,回收列级UPDATE权限时,Oracle不允许一列一列地回收,只能回收整个表的UPDATE权限。例如,
  GRANT UPDATE(SnoCno)
  ON SC
  TO U2
  把对SC表中Sno列和Cno列的UPDATE权限授予U2用户。
  REVOKE UPDATE ON SC FROM U2
  回收了U2用户对SC表中Sno列和Cno列的UPDATE权限。
  在Oracle中,表、行、列三级对象自上而下构成一个层次结构,其中上一级对象的权限制约下一级对象的权限。例如当一个用户拥有了对某个表的UPDATE权限,即相当于在表的所有列都拥有了UPDATE权限。
  Oracle对数据库对象的权限采用分散控制方式,允许具有WITH GRANT OPTION的用户把相应权限或其子集传递授予其他用户,但不允许循环授权,即被授权者不能把权限再授回给授权者或其祖先Oracle把所有权限信息记录在数据字典中。当用户进行数据库操作时,Oracle首先根据数据字典中的权限信息,检查操作的合法性。在Oracle中,安全性检查是任何数据库操作的第一步。
  三、Oracle的审计技术
  在Oracle中,审计分为用户级审计和系统级审计。用户级审计是任何Oracle用户可设置的审计,主要是用户针对自己创建的数据库表或视图进行审计,记录所有用户对这些表或视图的一切成功和(或)不成功的访问要求以及各种类型的SQL操作。
  系统级审计只能由DBA设置,用以监测成功或失败的登录要求、监测GRANTREVOKE操作以及其他数据库级权限下的操作。
  
  Oracle的审计功能很灵活,是否使用审计,对哪些表进行审计,对哪些操作进行审计等都可以由用户选择。为此,Oracle提供了AUDIT语句设置审计功能,NOAUDIT语句取消审计功能。设置审计时,可以详细指定对哪些SQL操作进行审计。例如,
  对修改SC表结构或数据的操作进行审计可使用如下语句:
   AUDIT ALTER UPDATE ON SC
  取消对SC表的一切审计可使用如下语句:
   NOAUDIT ALL ON SC
  在Oracle中,审计设置以及审计内容均存放在数据字典中。其中审计设置记录在数据字典表SYS.TABLES中,审计内容记录在数据字典表SYS.AUDIT_TRAIL中。
  四、用户定义的安全性措施
  除了系统级的安全性措施外,Oracle还允许用户用数据库触发器定义特殊的更复杂的用户级安全性措施。例如,规定只能在工作时间内更新Student表,可以定义如下触发器,其中sysdate为系统当前时间:
   CREATE OR REPLACE TRIGGER secure_student
   BEFORE INSERT OR UPDATE OR DELETE ON Student
   BEGIN
   IF (TO_CHAR(sysdate'DY') IN ('SAT''SUN'))
   OR (TO_NUMBER(sysdate'HH24') NOT BETWEEN 8 AND 17)
   THEN
   RAISE_APPLICATION_ERROR(-20506
   'You may only change data during normal business hours.')
   END IF
   END
  触发器一经定义便存放在数据字典中。用户每次对Student表执行INSERTUPDATEDELETE操作时都会自动触发该触发器,由系统检查当时的系统时间,如果是周六或周日,或者不是8点至17点,系统会拒绝执行用户的更新操作,并提示出错信息。
  类似地,用户还可以利用触发器进一步细化审计规则,使审计操作的粒度更细。
  综上所述,Oracle提供了多种安全性措施,提供了多级安全性检查,其安全性机制与操作系统的安全机制彼此独立,数据字典在Oracle的安全性授权和检查以及审计技术中起着重要作用。

第九章 数据库安全性

第五节 小结

  随着计算机特别是计算机网络的发展,数据的共享日益加强,数据的安全保密越来越重要。DBMS是管理数据的核心,因而其自身必须具有一整套完整而有效的安全性机制。
  《可信计算机系统评测标准》TCSEC/TDI是目前各国所引用或制定的一系列安全标准中最重要的一个。TCSEC/TDI从安全策略、责任、保证和文档四个方面描述了安全性级别的指标。按照这些指标,目前许多大型DBMS 达到了C2级,其安全版本达到了B1
  实现数据库系统安全性的技术和方法有多种,最重要的是存取控制技术和审计技术。C2级的DBMS必须具有自主存取控制功能和初步的审计功能,B1DBMS必须具有强制存取控制和增强的审计功能。自主存取控制功能一般是通过SQL GRANT语句和REVOKE语句来实现的。

第一节 完整性约束条件

  完整性检查是围绕完整性约束条件进行的,因此完整性约束条件是完整性控制机制的核心。
  完整性约束条件作用的对象可以是关系、元组、列三种。其中列约束主要是列的类型、取值范围、精度、排序等的约束条件。元组的约束是元组中各个字段间的联系的约束。关系的约束是若干元组间、关系集合上以及关系之间的联系的约束。
  
  完整性约束条件涉及的这三类对象,其状态可以是静态的,也可以是动态的。所谓静态约束是指数据库每一确定状态时的数据对象所应满足的约束条件,它是反映数据库状态合理性的约束,这是最重要的一类完整性约束。
  动态约束是指数据库从一种状态转变为另一种状态时,新、旧值之间所应满足的约束条件,它是反映数据库状态变迁的约束。
  综合上述两个方面,可以将完整性约束条件分为六类,
  一、静态列级约束
  二、静态元组约束
  三、静态关系约束
  四、动态列级约束
  五、动态元组约束
  六、动态关系约束

第十章 数据库完整性

第二节 完整性控制

  DBMS的完整性控制机制应具有三个方面的功能:
  · 定义功能,提供定义完整性约束条件的机制。
  · 检查功能,检查用户发出的操作请求是否违背了完整性约束条件。
  · 如果发现用户的操作请求使数据违背了完整性约束条件,则采取一定的动作来保证数据的完整性。
  完整性约束条件包括有六大类,约束条件可能非常简单,也可能极为复杂。一个完善的完整性控制机制应该允许用户定义所有这六类完整性约束条件。
  检查是否违背完整性约束的时机通常是在一条语句执行完后立即检查,称这类约束为立即执行约束(Immediate Constraints)。有时完整性检查需要延迟到整个事务执行结束后再进行,检查正确方可提交,称这类约束为延迟执行约束(Deferred Constraints)。例如银行数据库中"借贷总金额应平衡"的约束就应该是延迟执行的约束,从账号A转一笔钱到账号B为一个事务,从账号A转出去钱后账就不平了,必须等转入账号B后账才能重新平衡,这时才能进行完整性检查。
  如果发现用户操作请求违背了完整性约束条件,系统将拒绝该操作,但对于延迟执行的约束,系统将拒绝整个事务,把数据库恢复到该事务执行前的状态。
  
  一条完整性规则可以用一个五元组(DOACP)来表示,其中:
  · DData 约束作用的数据对象;
  · OOperation 触发完整性检查的数据库操作,即当用户发出什么操作请求时需要检查该完整性规则,是立即检查还是延迟检查;
  · AAssertion 数据对象必须满足的断言或语义约束,这是规则的主体;
  · CCondition 选择A作用的数据对象值的谓词;
  · PProcedure 违反完整性规则时触发的过程。
  例如,在"学号不能为空"的约束中
  D 约束作用的对象为Sno属性
  O 插入或修改Student 元组时
  A Sno不能为空
  C 无(A可作用于所有记录的Sno属性)
  P 拒绝执行该操作
  又如,在"教授工资不得低于1000"的约束中
  D 约束作用的对象为工资Sal属性
  O 插入或修改职工元组时
  A Sal不能小于1000
  C 职称=′教授A仅作用于职称=′教授的记录)
  P 拒绝执行该操作
  在关系系统中,最重要的完整性约束是实体完整性和参照完整性,其他完整性约束条件则可以归入用户定义的完整性。
  目前许多关系数据库管理系统都提供了定义和检查实体完整性、参照完整性和用户定义的完整性的功能。对于违反实体完整性和用户定义的完整性的操作一般都采用拒绝执行的方式进行处理。而对于违反参照完整性的操作,并不都是简单地拒绝执行,有时要根据应用语义执行一些附加的操作,以保证数据库的正确性。
  在2.3节中已讨论了关系系统中的实体完整性、参照完整性和用户定义的完整性的含义,下面详细讨论实现参照完整性要考虑的几个问题。
  1. 外码能否接受空值问题
  例如,职工-部门数据库包含职工表EMP和部门表DEPT,其中DEPT关系的主码为部门号DeptnoEMP关系的主码为职工号Empno,外码为部门号Deptno,称DEPT为被参照关系或目标关系,EMP为参照关系。
  EMP中,某一元组的Deptno列若为空值,表示这个职工尚未分配到任何具体的部门工作。这和应用环境的语义是相符的,因此EMPDeptno列可以取空值。但在学生-选课数据库中,Student关系为被参照关系,其主码为SnoSC为参照关系,外码为Sno。若SCSno为空值,则表明尚不存在的某个学生,或者某个不知学号的学生,选修了某门课程,其成绩记录在Grade列中。这与学校的应用环境是不相符的,因此SCSno列不能取空值。
  因此在实现参照完整性时,系统除了应该提供定义外码的机制,还应提供定义外码列是否允许空值的机制。
  2. 在被参照关系中删除元组的问题
  例如要删除Student关系中Sno=95001的元组,而SC关系中又有4个元组的Sno都等于95001,一般地,当删除被参照关系的某个元组,而参照关系存在若干元组,其外码值与被参照关系删除元组的主码值相同,这时可有三种不同的策略:
  (1)级联删除(CASCADES
  将参照关系中所有外码值与被参照关系中要删除元组主码值相同的元组一起删除。例如将上面SC关系中4Sno=95001的元组一起删除。如果参照关系同时又是另一个关系的被参照关系,则这种删除操作会继续级联下去。
  (2)受限删除(RESTRICTED
  仅当参照关系中没有任何元组的外码值与被参照关系中要删除元组的主码值相同时,系统才执行删除操作,否则拒绝此删除操作。例如对于上面的情况,系统将拒绝删除Student关系中Sno=95001的元组。
  (3)置空值删除(NULLIFIES
  删除被参照关系的元组,并将参照关系中相应元组的外码值置空值。例如将上面SC关系中所有Sno=950001的元组的Sno值置为空值。
  这三种处理方法,哪一种是正确的呢?这要依应用环境的语义来定。在学生-选课数据库中,显然第一种方法是对的。因为当一个学生毕业或退学后,他的个人记录从Student表中删除了,他的选课记录也应随之从SC表中删除。
  3. 在参照关系中插入元组时的问题
  例如向SC关系插入(99001190)元组,而Student关系中尚没有Sno=99001的学生,一般地,当参照关系插入某个元组,而被参照关系不存在相应的元组,其主码值与参照关系插入元组的外码值相同,这时可有以下策略:
  (1)受限插入
  仅当被参照关系中存在相应的元组,其主码值与参照关系插入元组的外码值相同时,系统才执行插入操作,否则拒绝此操作。例如对于上面的情况,系统将拒绝向SC关系插入(99001190)元组。
  (2)递归插入
  
  首先向被参照关系中插入相应的元组,其主码值等于参照关系插入元组的外码值,然后向参照关系插入元组。例如对于上面的情况,系统将首先向Student关系插入Sno=99001的元组,然后向SC关系插入(99001190)元组。
  4. 修改关系中主码的问题
  (1)不允许修改主码
  在有些RDBMS中,修改关系主码的操作是不允许的,例如不能用UPDATE语句将学号95001改为95102。如果需要修改主码值,只能先删除该元组,然后再把具有新主码值的元组插入到关系中。
  (2)允许修改主码
  在有些RDBMS中,允许修改关系主码,但必须保证主码的唯一性和非空,否则拒绝修改。
  当修改的关系是被参照关系时,还必须检查参照关系,是否存在这样的元组,其外码值等于被参照关系要修改的主码值。例如要将Student关系中Sno=950001Sno值改为960123,而SC关系中有4个元组的Sno=950001,这时与(上面第2点)在被参照关系中删除元组的的情况类似,可以有:级联修改、拒绝修改、置空值修改三种策略加以选择。
  当修改的关系是参照关系时,还必须检查被参照关系,是否存在这样的元组,其主码值等于被参照关系要修改的外码值。例如要把SC关系中(95001190)元组修改为(99001190),而Student关系中尚没有Sno=99001的学生,这时与(上面第3点)在参照关系中插入元组时的情况类似,可以有:受限插入和递归插入两种策略加以选择。
  从上面的讨论看到DBMS在实现参照完整性时,除了要提供定义主码、外码的机制外,还需要提供不同的策略供用户选择。选择哪种策略,都要根据应用环境的要求确定。

第十章 数据库完整性

第三节 Oracle的完整性

  上面介绍了完整性控制的一般方法,下面介绍Oracle的完整性控制策略。
  一、Oracle中的实体完整性
  OracleCREATE TABLE语句中提供了PRIMARY KEY子句,供用户在建表时指定关系的主码列。例如,在学生-选课数据库中,要定义Student表的Sno为主码,可使用如下语句:
   CREATE TABLE Student
   (Sno NUMBER(8)
   Sname VARCHAR(20)
   Sage NUMBER(20)
   CONSTRAINT PK_SNO PRIMARY KEY (Sno))
  其中,PRIMARY KEY(Sno)表示SnoStudent表的主码。PK_SNO是此主码约束名。
  若要在SC表中定义(Sno Cno)为主码,则用下面语句建立SC表:
   CREATE TABLE SC
   (Sno NUMBER(8)
   Cno NUMBER(2)
   Grade NUMBER(2)
   CONSTRAINT PK_SC PRIMARY KEY (SnoCno) )
  用PRIMARY KEY语句定义了关系的主码后,每当用户程序对主码列进行更新操作时,系统自动进行完整性检查,凡操作使主码值为空值或使主码值在表中不唯一,系统拒绝此操作,从而保证了实体完整性。
  二、Oracle中的参照完整性
  OracleCREATE TABLE语句也可以定义参照完整性规则,即用FOREIGN KEY子句定义哪些列为外码列,用REFERENCES子句指明这些外码相应于哪个表的主码,用ON DELETE CASCADE子语指明在删除被参照关系的元组时,同时删除参照关系中相应的元组。
  例如,使用如下SQL语句建立表EMP表:
   CREATE TABLE EMP
   (Empno NUMBER(4)
   Ename VARCHAR(10)
   Job VARCHAR2(9)
   Mgr NUMBER(4)
   Sal NUMBER(72)
   Deptno NUMBER(2)
   CONSTRAINT FK_DEPTNO
   FOREIGN KEY (Deptno)
   REFERENCES DEPT(Deptno) )
  则表明EMP是参照表,DEPT为其被参照表,EMP表中Deptno为外码,它相应于DEPT表中的主码Deptno。当删除或修改DEPT表中某个元组的主码时要检查EMP中是否有元组的DEPTNO值等于DEPT中要删除的元组的Deptno值,如没有,接受此操作;否则系统拒绝这一更新操作。
  如果用如下SQL语句建立EMP表:
   CREATE TABLE EMP
   (Empno NUMBER(4)
   Ename VARCHAR(10)
   Job VARCHAR2(9)
   Mgr NUMBER(4)
   Sal NUMBER(72)
   Deptno NUMBER(2)
   CONSTRAINT FK_DEPTNO
   FOREIGN KEY (Deptno)
   REFERENCES DEPT(Deptno)
   ON DELETE CASCADE)
  当要修改DEPT表中的Deptno值时,先要检查EMP表中有无元组的Deptno值与之对应,若没有,系统接受这个修改操作,否则,系统拒绝此操作。
  当要删除DEPT表中某个元组时,系统也要检查EMP表,若找到相应元组则将它们也随之删除。
  三、Oracle中用户定义的完整性
  除实体完整性和参照完整性外,应用系统中往往还需要定义与应用有关的完整性限制。例如:要求某一列的值不能取空值,要在表中是唯一的,要在某个取值范围中等。Oracle允许用户在建表时定义下列完整性约束:
  · 列值非空(NOT NULL短语)
  · 列值唯一(UNIQUE短语)
  · 检查列值是否满足一个布尔表达式(CHECK短语)

第十章 数据库完整性

第四节 小结

  数据库的完整性是为了保证数据库中存储的数据是正确的,所谓正确的是指符合现实世界语义的。本章讲解了DBMS完整性实现的机制,包括完整性约束定义机制、完整性检查机制和违背完整性约束条件时DBMS应采取的动作等。
  完整性机制的实施会极大地影响系统性能,因此,许多数据库管理系统对完整性机制的支持比对安全性的支持要晚得多也弱得多。随着硬件性能和容量的提高,数据库技术的发展,许多数据库厂商对完整性的支持越来越好,不仅在能保证实体完整性和参照完整性而且能在DBMS核心定义、检查和保证用户定义的完整性约束条件。读者应注意,不同的数据库产品对完整性的支持策略和支持程度是不同的。

 



评论Comment

↓↓↓↓
取消留言

公告Notice

欢迎加入谷歌blogger交流群:125691905 设计:臧超 by臧超地理工作室 Github代码 本站开源 网站大部分内容来自网络 如有侵权请联系我们删除
Copyright © 臧超地理频道 | Powered by Blogger Design by ronangelo | Blogger Theme by NewBloggerThemes.com
Theme:http://newbloggerthemes.com/frontier-blogger-template/