数据库系统原理教程习题答案第9章习题
- 格式:pdf
- 大小:208.69 KB
- 文档页数:5
9.1 名词解释(1)OODBS:是指面向对象数据库系统,它既具数据库管理的基本功能,又能支持面向对象的数据模型。
(2)ORDBS:基于对象关系数据模型的DBS称为对象关系数据库系统(ORDBS)。
(3)平面关系模型:传统的关系模型称为“平面关系模型”,它要求关系模式具有第一范式(1NF)性质,关系具有规范化的结构。
也就是规定属性值是不可分解的,即不允许属性值具有复合结构(元组或关系)。
(4)嵌套关系模型:是从平面关系模型发展而成的。
它允许关系的属性值又可以是一个关系,而且可以出现多次嵌套。
嵌套关系突破了1NF的定义框架,是“非1NF关系”。
(5)复合对象模型:在嵌套关系模型上进一步放宽要求。
在关系定义上,集合与元组不再有交替出现的严格限制,此时的关系中,属性类型可以是基本数据类型、结构类型(元组类型)或集体类型(即关系类型)。
(6)数据的泛化/细化:是对概念之间联系进行抽象的一种方法。
当在较低层上的抽象表达了与之联系的较高层上抽象的特殊情况时,就称较高层上抽象是较低层上抽象的"泛化",而较低层上抽象是较高层上抽象的"细化"。
(7)对象关系模型:在传统关系数据基础上,提供元组、数组、集合等更为丰富的数据类型及处理新数据类型操作的能力而形成的数据模型。
(注:传统关系模型只支持字符、数值、字串,布尔值等等基本数据类型及其处理功能)(8)类型级继承性:当继承性发生在类型级时,子类型继承了超类型的属性。
也就是说,超类型所具有的属性,在子类上也具有。
(9)表级继承性:继承性也可发生在表级,(就是元组集合上发生继承),子表继承超表全部属性,超表中每个元组最多可以与子表中一个元组对应,而子表中的每个元组在超表中恰有一个元组对应,并在继承的属性值上具有相同的值。
(10)引用类型:数据类型可以嵌套定义,在嵌套引用时,不是引用对象本身,而是个用对象标识符(即指针),这种指针被称为引用类型。
数据库系统原理课后习题第一章. 数据库系统基本概念1.1.名词解释DB——DB是长期存储在计算机内、有组织的、统一管理的相关数据的集合。
DB能为各种用户共享,具有较小冗余度、数据间联系紧密而又有较高的数据独立性等特点。
DBMS——是位于用户与操作系统之间的一层数据管理软件,它为用户或应用程序提供访问DB的方法,包括DB的建立、查询、更新及各种数据控制。
DBS——是实现有组织地、动态地存储大量关联数据、方便多用户访问的计算机硬件、软件和数据资源组成的系统,即它是采用数据库技术的计算机系统。
联系——是实体间的相互关系。
联系的元数——与一个联系有关的实体集个数。
1:1联系——如果实体集E1中每个实体至多和实体集E2中一个实体有联系,反之亦然,那么实体集E1和E2的联系称为“一对一联系”,记为“1:1”。
1:N联系——如果实体集E1中的每个实体可以与实体集E2中的任意个(0个或多个)实体有联系,而E2中的每个实体至多和E1中的一个实体有联系,那么称E1对E2的联系是一对多联系,记作:“1:N ”。
M:N联系——如果实体集E1中的每个实体可以与实体集E2中的任意个(0个或多个)实体有联系,反之亦然,那么称E1和E2的联系是“多对多联系”,记作“M:N”。
数据模型——在数据库技术中,我们用数据模型的概念描述数据库的结构和语义,对现实世界的数据进行抽象。
根据数据抽象级别定义了四种模型:概念数据模型、逻辑数据模型、外部数据模型和内部数据模型。
概念模型——表达用户需求观点的数据全局逻辑结构的模型。
逻辑模型——表达计算机实现观点的DB全局逻辑结构的模型。
主要有层次、网状、关系模型等三种。
外部模型——表达用户使用观点的DB局部逻辑结构的模型。
内部模型——表达DB物理结构的模型。
层次模型——用树型(层次)结构表示实体类型及实体间联系的数据模型。
网状模型——用有向图结构表示实体类型及实体间联系的数据模型。
关系模型——是由若干个关系模式组成的集合。
USE ScoreDBGO--9.6 在学生成绩管理数据库ScoreDB中完成。
--(1) 在班级表Class中,分别使用列级和元组级约束保证班级人数classNum属性的取值在(0,50)之间。
--为避免误删Class表的数据,另建两表演示,演示后删除--列级约束CREATE TABLE Class1(classNo char(6) PRIMARY KEY, /*班级编号*/className varchar(30) NOT NULL, /*班级名称*/institute varchar(30) NOT NULL, /*所属学院*/grade smallint NOT NULL /*年级*/DEFAULT 0,classNum tinyint NULL /*班级人数*/CHECK(classNum >=0 AND classNum <= 50))--元组级约束CREATE TABLE Class2(classNo char(6) PRIMARY KEY, /*班级编号*/className varchar(30) NOT NULL, /*班级名称*/institute varchar(30) NOT NULL, /*所属学院*/grade smallint NOT NULL /*年级*/DEFAULT 0,classNum tinyint NULL, /*班级人数*/CONSTRAINT CK_Class_classNum CHECK(classNum >=0 AND classNum <= 50))--删除演示表DROP TABLE Class1DROP TABLE Class2GO--(2) 在学生表Student中,限制籍贯为上海或北京的学生的年龄必须在17岁以上。
--需要使用触发器CREATE TRIGGER Student_birthdayON StudentFOR INSERT,UPDATEASIF EXISTS(SELECT * FROM inserted WHERE YEAR(GETDATE())-YEAR(birthday)<17) ROLLBACKGO--(3) 对于某门课程,保证如果没有选修其先修课程,则不能选修该课程。
第九章一、填空题1.数据库2.原子3.START TRANSACTION4.AUTOCOMMIT5.READ UNCOMMITTED二、判断题对1.对2.对3.错4.对5.对三、选择题1. C2.B、C、D3. B4. B5. D四、简单题1.请简述什么是事务。
答:在MySQL中,事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,且每个SQL语句是相互依赖的。
只要在程序执行过程中有一条SQL语句执行失败或发生错误,则其他语句都不会执行。
也就是说,事务的执行要么成功,要么就返回到事务开始前的状态,这就保证了同一事务操作的同步性和数据的完整性。
2.请简述什么是事务的ACID特性。
答:①原子性是指一个事务必须被视为一个不可分割的最小工作单元。
②一致性是指在事务处理时,无论执行成功还是失败,都要保证数据库系统处于一致的状态,保证数据库系统从不返回到一个未处理的事务中。
③隔离性是指当一个事务在执行时,不会受到其他事务的影响。
④持久性是指事务一旦提交,其对数据库的修改就是永久性的。
五、实训题1.请利用事务实现在用户下订单时,检查商品库存是否充足。
START TRANSACTION;1# 查询id为1的商品的库存SELECT stock FROM sh_goods WHERE id = 1;# 根据结果回滚或提交COMMIT;2.请利用事务在用户下订单前,检测当前用户是否已被激活,若未激活,则需激活此用户后,才能再次下订单。
START TRANSACTION;# 查询id为1的用户是否激活SELECT is_active FROM sh_user WHERE id = 1;# 根据结果回滚或提交COMMIT;2。
第九章T-SQL基础P1641.从功能上划分,SQL分为哪4类?[难度↓]【解】SQL语句通常分成以下4类:数据查询语言数据操作语言数据定义语言数据控制语言2.NULL代表什么含义?将其与其他值进行比较会产生什么结果?如果数值型列中存在NULL,会产生什么结果?[难度↓]【解】在数据库中,NULL是一个特殊值,表示数值未知。
NULL不同于空字符或数字0,也不同于零长度字符串。
比较两个空值或将空值与任何其他数值相比均返回未知,这是因为每个空值均为未知。
空值通常表示未知、不可用或以后添加数据。
如果某个列上的空值属性为NULL,表示接受空值;空值属性为NOT NULL,表示拒绝空值。
如果数值型列中存在NULL,则在进行数据统计时就会产生不正确的结果。
3.使用T-SQL语句向表中插入数据应注意什么?[难度↓]【解】在使用T-SQL语句向表中插入数据时要注意以下几点:当向表中所有列都插入新数据时,可以省略列表名,但是必须保证VALUES 后的各数据项位置同表定义时的顺序一致。
要保证表定义时的非空列必须有值,即使这个非空列没有出现在插入语句中,也必须如此。
插入字符型和日期型值时,要加入单引号。
没有列出的数据类型应该具有以下属性之一:identity属性、timestamp 数据类型、具有NULL属性或者有一个默认值。
对于具有identity属性的列,其值由系统给出,用户不必往表中插入数据。
4.在SELECT语句中DISTINCT、ORDER BY、GROUP BY和HA VING子句的功能各是什么?[难度↓]【解】各子句的功能如下。
DISTINCT:查询唯一结果。
ORDER BY:使查询结果有序显示。
GROUP BY:对查询结果进行分组。
HA VING:筛选分组结果。
5.在一个SELECT语句中,当WHERE子句、GROUP BY子句和HA VING子句同时出现在一个查询中时,SQL的执行顺序如何?[难度↓↓]【解】其执行顺序如下:(1)执行WHERE子句,从表中选取行。
第一章习题参考答案1.名词解释:数据、数据库、数据库管理系统、数据库系统、关系数据库管理系统。
数据:用来记录或者标识事物本质特征的符号。
具体包括文本、图形、图像、音频、视频、动画等数据。
数据库:长期储存在计算机内的有组织的、统一的、共享的、结构化的、通用化的、综合性的数据的集合。
数据库管理系统:位于用户与操作系统之间,提供给用户实现数据库的定义、操纵和运行管理的数据管理软件,从而科学地组织和存储数据、高效地获取和维护数据。
数据库系统:在计算机系统中引入数据库后,由数据库、数据库管理系统、数据库应用系统、数据库设计员、数据库管理员和用户等构成的完整的计算机系统。
DBS的核心是数据库管理系统,DBMS是用户与数据库的接口关系数据库系统:支持关系数据库技术的数据库系统。
2.简述数据库管理系统的功能。
数据定义DDL;数据操纵DML;数据控制DCL(安全性、完整性、并发控制和数据恢复);数据接口;数据组织和存储;事务和运行管理等。
从而确保数据的安全、完整、并发和恢复。
3.简述数据库系统的组成和特点。
组成:DBS硬件(计算机硬件、数据库硬件和网络硬件等)、DBS软件(操作系统、DBMS、程序设计主语言、数据库专用开发工具和数据库应用系统等)和人员(数据库设计员、数据库分析员、数据库管理员、数据库程序员和用户)等组成。
特点:数据结构化组织、永久储存和统一管理;数据共享;冗余度小;独立性高;容易扩展等。
4.常用的数据模型有哪些?简述数据模型的三个要素。
类型:层次模型(最早);网状模型;关系模型(目前流行);面向对象模型(20世纪80年代引入OOP)。
要素:数据结构;数据操作;完整性约束。
5.简述DBA的职责。
决定数据库的信息内容和结构;决定数据库的存储结构和存取策略;定义数据的安全性和完整性;监控数据库的使用和运行;数据库的改进和重组重构。
6.简述数据库技术发展的三个基本阶段。
人工管理;文件系统;数据库系统7.试述文件系统与数据库系统的区别。
第一部分基础理论第1章数据库概述1.试说明数据、数据库、数据库管理系统和数据库系统的概念。
数据:描述事务的符号记录数据库:存储数据的仓库数据库管理系统:用于管理和维护数据的系统软件数据库系统:计算机中引入数据库后的系统,包括数据库,数据库管理系统,应用程序,数据库管理员2.数据管理技术的发展主要经历了哪几个阶段?两个阶段,文件管理和数据库管理9.数据独立性指的是什么?应用程序不因数据的物理表示方式和访问技术改变而改变,分为逻辑独立性和物理独立性。
物理独立性是指当数据的存储结构或存储位置发生变化时,不影响应用程序的特性;逻辑独立性是指当表达现实世界的信息内容发生变化时,不影响应用程序的特性。
10.数据库系统由哪几部分组成?由数据库、数据库管理系统、应用程序、数据库管理员组成。
第2章数据模型与数据库系统的结构4.说明实体一联系模型中的实体、属性和联系的概念。
实体是具有公共性质的并可相互区分的现实世界对象的集合。
属性是实体所具有的特征或性质。
联系是实体之间的关联关系。
6.数据库系统包含哪三级模式?试分别说明每一级模式的作用。
外模式、模式和内模式。
外模式:是对现实系统中用户感兴趣的整体数据结构的局部描述,用于满足不同用户对数据的需求,保证数据安全。
模式:是数据库中全体数据的逻辑结构和特征的描述,它满足所有用户对数据的需求。
内模式:是对整个数据库的底层表示,它描述了数据的存储结构。
7.数据库管理系统提供的两级映像的作用是什么?它带来了哪些功能?两级映像是外模式/模式映像和模式/内模式映像。
外模式/模式映像保证了当模式发生变化时可以保证外模式不变,从而使用户的应用程序不需要修改,保证了程序与数据的逻辑独立性。
模式/内模式映像保证了当内模式发生变化,比如存储位置或存储文件名改变,可以保持模式不变,保证了程序与数据的物理独立性。
两级印象保证了应用程序的稳定性。
第3章关系数据库1.试述关系模型的三个组成部分。
数据结构、关系操作集合、关系完整性约束2.解释下列术语的含义:(3)候选码当一个属性或属性集的值能够唯一标识一个关系的元组,而又不包含多余的元素,则称该属性或属性集为候选码。
数据库原理课后习题及解答(常用版)(可以直接使用,可编辑完整版资料,欢迎下载)《数据库原理》课后习题及解答课后习题:第一章第二章第三章第四章第五章第六章第七章第八章第九章习题答案:第一章第二章第三章第四章第五章第六章第七章第八章第九章第一章概论1.试解释下列术语:数据库;数据库管理系统;数据库系统2.试述数据库管理系统的组成内容。
3.试比较文件系统与数据库系统的异同。
4.什么叫数据的物理独立性与逻辑独立性?并说明它的重要性。
5.试述数据库系统的优点。
6.什么叫数据的冗余与数据的不一致性?7.什么叫数据库管理员?他的主要工作是什么?8.试述数据库系统发展的几个阶段。
返回第一章答案第二章数据模型1.什么叫数据库模型,它分哪几种类型?2.试区别数据模型与数据模式。
3.什么叫数据模式,它分哪三级?4.试述数据模型四个世界的基本内容。
5.试介绍E-R模型,EE-R模型及面向对象模型、谓词模型,并各举一例说明之。
6.层次网状模型有什么特点?并各举一例说明之。
7.试比较层次、网状、关系模型之优缺点。
8.试说明关系模型的基本结构与操作。
9.目前流行的关系型数据库管理系统,有哪些你比较熟悉,试介绍其特点。
10.你认为“数据模型”在整个数据库领域中是否有重要作用和地位,试详细说明之。
11.一图书馆借阅书刊,请你画出书刊、读者及借阅三者间的E-R模型。
12.一人事档案中,有干部、职工,干部又有高级干部与一般干部,请用EE-R模型画出他们之间关系。
13.试述物理模型的主要内容。
14.试叙述四个世界的转化关系。
15.请你比较四种数据模型的异同。
返回第二章答案第三章关系数据库系统1.试述关系数据库系统的优点。
2.试述关系型的12条标准,并说明FOXBASE为何是半关系型的。
3.关系代数与关系演算的表示能力是否相同?试证明之。
4.从关系模型的数学表示中,你是否认为网状与层次模型也可以用数学方法表示?试说明理由。
5.设有如图3-1所示的医院组织。
数据库系统原理版课后习题参考答案答案仅供参考第一章数据库系统概述选择题B、B、A简答题1.请简述数据,数据库,数据库管理系统,数据库系统的概念。
P27数据是描述事物的记录符号,是指用物理符号记录下来的,可以鉴别的信息。
数据库即存储数据的仓库,严格意义上是指长期存储在计算机中的有组织的、可共享的数据集合。
数据库管理系统是专门用于建立和管理数据库的一套软件,介于应用程序和操作系统之间。
数据库系统是指在计算机中引入数据库技术之后的系统,包括数据库、数据库管理系统及相关实用工具、应用程序、数据库管理员和用户。
2.请简述早数据库管理技术中,与人工管理、文件系统相比,数据库系统的优点。
数据共享性高数据冗余小易于保证数据一致性数据独立性高可以实施统一管理与控制减少了应用程序开发与维护的工作量3.请简述数据库系统的三级模式和两层映像的含义。
P31答:数据库的三级模式是指数据库系统是由模式、外模式和内模式三级工程的,对应了数据的三级抽象。
两层映像是指三级模式之间的映像关系,即外模式/模式映像和模式/内模式映像。
4.请简述关系模型与网状模型、层次模型的区别。
P35使用二维表结构表示实体及实体间的联系建立在严格的数学概念的基础上概念单一,统一用关系表示实体和实体之间的联系,数据结构简单清晰,用户易懂易用存取路径对用户透明,具有更高的数据独立性、更好的安全保密性。
.第二章关系数据库选择题C、C、D简答题1.请简述关系数据库的基本特征。
P48答:关系数据库的基本特征是使用关系数据模型组织数据。
2.请简述什么是参照完整性约束。
P55答:参照完整性约束是指:若属性或属性组F是基本关系R的外码,与基本关系S的主码K相对应,则对于R中每个元组在F上的取值只允许有两种可能,要么是空值,要么与S中某个元组的主码值对应。
3.请简述关系规范化过程。
答:对于存在数据冗余、插入异常、删除异常问题的关系模式,应采取将一个关系模式分解为多个关系模式的方法进行处理。
0000000000第1章数据库系统概述习题参考答案税务局使用数据库存储纳税人(个人或公司)信息、纳税人缴纳税款信息等。
典型的数据处理包括纳税、退税处理、统计各类纳税人纳税情况等。
银行使用数据库存储客户基本信息、客户存贷款信息等。
典型的数据处理包括处理客户存取款等。
超市使用数据库存储商品的基本信息、会员客户基本信息、客户每次购物的详细清单。
典型的数据处理包括收银台记录客户每次购物的清单并计算应交货款。
1.2 DBMS是数据库管理系统的简称,是一种重要的程序设计系统。
它由一个相互关联的数据集合和一组访问这些数据的程序组成。
数据库是持久储存在计算机中、有组织的、可共享的大量数据的集合。
数据库中的数据按一定的数据模型组织、描述和存储,可以被各种用户共享,具有较小的冗余度、较高的数据独立性,并且易于扩展。
数据库系统由数据库、DBMS(及其开发工具)、应用系统和数据库管理员组成。
数据模型是一种形式机制,用于数据建模,描述数据、数据之间的联系、数据的语义、数据上的操作和数据的完整性约束条件。
数据库模式是数据库中使用数据模型对数据建模所产生设计结果。
对于关系数据库而言,数据库模式由一组关系模式构成。
数据字典是DBMS维护的一系列内部表,用来存放元数据。
所谓元数据是关于数据的数据。
1.3 DBMS提供如下功能:(1)数据定义:提供数据定义语言DDL,用于定义数据库中的数据对象和它们的结构。
(2)数据操纵:提供数据操纵语言DML,用于操纵数据,实现对数据库的基本操作(查询、插入、删除和修改)。
(3)事务管理和运行管理:统一管理数据、控制对数据的并发访问,保证数据的安全性、完整性,确保故障时数据库中数据不被破坏,并且能够恢复到一致状态。
(4)数据存储和查询处理:确定数据的物理组织和存取方式,提供数据的持久存储和有效访问;确定查询处理方法,优化查询处理过程。
(5)数据库的建立和维护:提供实用程序,完成数据库数据批量装载、数据库转储、介质故障恢复、数据库的重组和性能监测等。
数据库原理与应用第9章答案解析主编肖海蓉、任民宏第9章数据库的备份与恢复9.1数据库的备份9.1.1备份的相关概念9.1.2SQLServer2012数据备份方式9.1.3SQLServer2012备份设备的管理9.1.4SQLServer2012数据库备份9.2数据库的恢复9.2.1SQLServer2012数据恢复模型9.2.2SQLServer2012数据库恢复9.2.3SQLServer2012数据库的分离和附加9.3数据的转换9.3.1SQLServer2012数据导出9.3.2SQLServer2012数据导入本章小结习题9第9 章数据库的备份与恢复课后习题参考答案1、简答题(1)简述SQL Server 2012 数据备份方式,并说明它们之间的区别。
答:SQL Server 2012 中把数据备份分为数据库备份、文件及文件组备份两大类。
①数据库备份分为完整备份、差异备份、事务日志备份。
其中完整备份是将整个数据库的所有数据及数据库对象完全复制到备份文件中;增量备份也称为差异备份,是完整备份的补充;这种备份方式须首先执行过一次完整备份,之后每次增量备份仅是备份最近一次完全备份以后数据库发生变化的数据;事务日志备份即备份发生在数据库上的事务,只备份事务日志中的内容。
完整备份比较容易理解,即备份一个完整数据库的当前所有内容,日志备份和增量备份都是在数据库完整备份的基础上备份后期数据库变动更新的内容,二者的区别是各自备份的起点不同。
②文件与文件组备份;若在创建数据库时建立了多个数据库文件或文件组,则可以使用文件和文件组备份方式。
一般可以将数据库文件组和文件存储在不同的备份设备上,通常应用于经常更新的超大型数据库或分布在多个文件的数据库,是比较复杂的备份。
(2)简述如何创建备份设备。
答:备份设备可以通过SQL Server Management Studio 或T-SQL 语言来实现。
1)使用SQL Server Management Studio 创建备份设备;①在对象资源管理器中,展开“服务器名称”→“服务器对象”→“备份设备”节点,右击“备份设备”节点,出现备份设备快捷菜单。
1.试述实现数据库安全性控制的常用方法和技术。
数据库安全性控制的常用技术包括用户标识与鉴别、存取控制、视图机制、审计、密码保护等。
2.什么是数据库中的自主存取控制方法和强制存取控制方法?在自主存取控制方法中,用户对于不同的数据对象有不同的存取权限,不同的用户对同一对象也有不同的权限,而且用户还可将其拥有的存取权限转授给其他用户。
DBMS通过验证用户是否具有对访问数据有相应的权限来决定是否允许用户执行数据访问。
在强制存取控制中,DBMS所管理的全部实体被分为主体和客体两大类。
主体和客体都具有自己的安全级别。
但主体访问客体时,不仅要求主体具有访问客体的权限,而且要求主体的安全级和客体的安全级之间满足支配关系。
3.DBMS的完整性控制机制应具有哪些功能?DBMS的数据库完整性控制机制应具有以下三个功能:(1)定义功能:提供定义完整性约束条件的机制;(2)检查功能:检查用户发出的操作请求是否违背了约束条件。
一般有两种检查方式:一种是立即执行约束(即一条语句执行完成后立即检查),另一种是延迟执行约束(即在整个事务执行完毕后再检查约束);(3)违约响应功能:如果操作请求使数据违背了完整性约束条件,则采取一定的动作来保证数据的完整性。
4.试述事务的概念及事务的四个特性。
数据库系统中的事务是一个不可分的操作序列,其中的操作要么全部都不执行,要把全部都执行。
事务一般应满足四个性质,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
这四个性质在数据库领域中一般合称为事务的ACID性质。
(1)原子性事务的原子性是指一个事务内部的所有操作要么全部都执行,要么一个也不执行,即所有操作是一个整体。
(2)一致性事务的一致性是指事务的执行保证数据库从一个一致状态转到另一个一致状态,即数据不会应事务的执行而导致不一致。
但是,事务的内部无须满足数据库的一致性。
第1章绪论1 .试述数据、数据库、数据库系统、数据库管理系统的概念。
答:( l )数据(Data ) :描述事物的符号记录称为数据。
数据的种类有数字、文字、图形、图像、声音、正文等。
数据与其语义是不可分的。
解析在现代计算机系统中数据的概念是广义的。
早期的计算机系统主要用于科学计算,处理的数据是整数、实数、浮点数等传统数学中的数据。
现代计算机能存储和处理的对象十分广泛,表示这些对象的数据也越来越复杂。
数据与其语义是不可分的。
500 这个数字可以表示一件物品的价格是500 元,也可以表示一个学术会议参加的人数有500 人,还可以表示一袋奶粉重500 克。
( 2 )数据库(DataBase ,简称DB ) :数据库是长期储存在计算机内的、有组织的、可共享的数据集合。
数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种用户共享。
( 3 )数据库系统(DataBas 。
Sytem ,简称DBS ) :数据库系统是指在计算机系统中引入数据库后的系统构成,一般由数据库、数据库管理系统(及其开发工具)、应用系统、数据库管理员构成。
解析数据库系统和数据库是两个概念。
数据库系统是一个人一机系统,数据库是数据库系统的一个组成部分。
但是在日常工作中人们常常把数据库系统简称为数据库。
希望读者能够从人们讲话或文章的上下文中区分“数据库系统”和“数据库”,不要引起混淆。
( 4 )数据库管理系统(DataBase Management sytem ,简称DBMs ) :数据库管理系统是位于用户与操作系统之间的一层数据管理软件,用于科学地组织和存储数据、高效地获取和维护数据。
DBMS 的主要功能包括数据定义功能、数据操纵功能、数据库的运行管理功能、数据库的建立和维护功能。
解析DBMS 是一个大型的复杂的软件系统,是计算机中的基础软件。
目前,专门研制DBMS 的厂商及其研制的DBMS 产品很多。
第九章一问答题试题1 满分值:10.0分状态:未答实际得分:分试题:试述查询处理的基本过程。
[参考答案]RDBMS查询处理过程:(1). 查询分析;对查询语句进行扫描、词法分析和语法分析,从查询语句中识别出语言符号,进行语法检查和语法分析。
(2). 查询检查;根据数据字典对合法的查询语句进行语义检查,根据数据字典中的用户权限和完整性约束定义对用户的存取权限进行检查,检查通过后把SQL查询语句转换成等价的关系代数表达式,RDBMS一般都用查询树(语法分析树)来表示扩展的关系代数表达式把数据库对象的外部名称转换为内部表示。
(3). 查询优化;查询优化:选择一个高效执行的查询处理策略。
(4). 查询执行;依据优化器得到的执行策略生成查询计划,代码生成器(Code Generator)生成执行查询计划的代码。
[我的答案]试题2 满分值:10.0分状态:未答实际得分:分试题:什么是代数优化,什么是物理优化?[参考答案]通过对关系代数表达式的等价变换来提高查询效率,即有选择和连接操作时,先做选择操作,这样参加连接的元组就可以大大减少,这是代数优化。
物理优化:SC表的选择操作算法有全表扫描和索引扫描2种方法,经过初步估算,索引扫描方法较优,对于Student和SC表的连接,利用 Student表上的索引,采用index join代价也较小,这就是物理优化。
物理优化就是要选择高效合理的操作算法或存取路径,求得优化的查询计划。
[我的答案]试题3 满分值:10.0分状态:未答实际得分:分试题:试述查询优化的一般步骤。
[参考答案]各个关系系统的优化方法不尽相同,大致的步骤可以归纳如下:( l )把查询转换成某种内部表示,通常用的内部表示是语法树。
( 2 )把语法树转换成标准(优化)形式。
即利用优化算法,把原始的语法树转换成优化的形式。
( 3 )选择低层的存取路径。
( 4 )生成查询计划,选择代价最小的。
试题:试述查询优化的一般准则。
9.3.1a)In the following, we use macro NOT_FOUND as defined in the section.void closestMatchPC() {EXEC SQL BEGIN DECLARE SECTION;char manf, SQLSTATE[6];int targetPrice, /* holds price given by user */float tempSpeed, speedOfClosest;char tempModel[4], modelOfClosest[4];int tempPrice, priceOfClosest;/* for tuple just read from PC & closest price found so far */EXEC SQL END DECLARE SECTION;EXEC SQL DECLARE pcCursor CURSOR FORSELECT model, price, speed FROM PC;EXEC SQL OPEN pcCursor;/* ask user for target price and read the answer into variabletargetPrice *//* Initially, the first PC is the closest to the target price.If PC is empty, we cannot answer the question, and so abort. */EXEC SQL FETCH FROM pcCursorINTO :modelOfClosest, :priceOfClosest, :speedOfClosest;if(NOT_FOUND) /* print message and exit */ ;while(1) {EXEC SQL FETCH pcCursor INTO :tempModel, :tempPrice,:tempSpeed;if(NOT_FOUND) break;if(/*tempPrice closer to targetPrice than is priceOfClosest */){modelOfClosest = tempModel;priceOfClosest = tempPrice;speedOfClosest = tempSpeed;}}/* Now, modelOfClosest is the model whose price is closest totarget. We must get its manufacturer with a single-row select */EXEC SQL SELECT makerINTO :manfFROM ProductWHERE model = :modelOfClosest;printf("manf=%s, model=%d, speed=%d\n",manf, modelOfClosest, speedOfClosest);EXEC SQL CLOSE CURSOR pcCursor;}b)void acceptableLaptop() {EXEC SQL BEGIN DECLARE SECTION;int minRam, minHd, minScreen; /* given by user */float minSpeed;char model[4], maker,float speed;int ram, hd, screen, price;EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE query1 FROM‘ SELECT model, speed, ram, hd, screen, price, maker FROM Laptop l, Product pWHERE speed >= ?AND ram >= ? ANDhd >= ? ANDscreen >= ? ANDl.model = p.model’EXEC SQL DECLARE cursor1 CURSOR FOR query1;/* ask user for minimum speed, ram, hd size, and screen size */EXEC SQL OPEN cursor1 USING :minSpeed, :minRam, :minHd, :minScreen;while(!NOT_FOUND) {EXEC SQL FETCH cursor1 INTO:model, :speed, :ram, :hd, :screen, :price, :maker;if(FOUND){printf("maker:%s, model:%d, \nspeed:%.2f, ram:%d, hd:%d, screen:%d, price:%d\n",maker, model, speed, ram, hd, screen, price);}}EXEC SQL CLOSE CURSOR cursor1;}c)void productsByMaker() {EXEC SQL BEGIN DECLARE SECTION;char maker, model[4], type[10], color[6];float speed;int ram, hd, screen, price;EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE query1 FROM‘ SELECT * FROM PCWHERE model IN (SELECT model FROM ProductWHERE maker = ? ANDtype =‘ pc’ );EXEC SQL PREPARE query2 FROM‘ SELECT * FROM LaptopWHERE model IN (SELECT model FROM ProductWHERE maker = ? ANDtype =‘ laptop’ );EXEC SQL PREPARE query3 FROM‘ SELECT * FROM PrinterWHERE model IN (SELECT model FROM ProductWHERE maker = ? ANDtype =‘ printer’ );EXEC SQL DECLARE cursor1 CURSOR FOR query1;EXEC SQL DECLARE cursor2 CURSOR FOR query2;EXEC SQL DECLARE cursor3 CURSOR FOR query3;/* ask user for manufacturer */Printf(“ maker:%s n” , ma ker);/* get PCs made by the manufacturer */EXEC SQL OPEN cursor1 USING :maker;Printf( “ product type: PC n” );while(!NOT_FOUND) {EXEC SQL FETCH cursor1 INTO:model, :speed, :ram, :hd, :price;if(FOUND){n” , model, speed, ram, hd, price);}}/* get Laptops made by the manufacturer */EXEC SQL OPEN cursor2 USING :maker;Printf(“ product type: Laptop n” );while(!NOT_FOUND) {EXEC SQL FETCH cursor2 INTO:model, :speed, :ram, :hd, :screen, :price;if(FOUND){printf("model:%d, speed:%.2f, ram:%d, hd:%d, screen:%d,price:%d\n", model, speed, ram, hd, screen, price);}}/* get Printers made by the manufacturer */EXEC SQL OPEN cursor3 USING :maker;Printf(“ product type: Printer n”);while(!NOT_FOUND) {EXEC SQL FETCH cursor3 INTO:model, :color, :type, :price;if(FOUND){printf("model:%d, color:%s, type:%s, price:%d\n",model, color, type, price);}}EXEC SQL CLOSE CURSOR cursor1;EXEC SQL CLOSE CURSOR cursor2;EXEC SQL CLOSE CURSOR cursor3;}d)void withinBudget() {EXEC SQL BEGIN DECLARE SECTION;int total_budget, rest_budget, pc_price, printer_price;char pc_model[4], printer_model[4], color[6];float min_speed;EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE query1 FROM‘ SELECT model, price FROM PCWHERE speed >= ? AND price <= ?ORDER BY price’;EXEC SQL PREPARE query2 FROM‘ SELECT model, price FROM PrinterWHERE price <= ? AND color = ?ORDER BY price’;EXEC SQL DECLARE cursor1 CURSOR FOR query1;EXEC SQL DECLARE cursor2 CURSOR FOR query2;/* ask user for budget & the minimum speed of pc *//* get the cheapest PC of the minimum speed */EXEC SQL OPEN cursor1 USING :min_speed, :total_budget;EXEC SQL FETCH cursor1 INTO :pc_model, :pc_price;if (NOT_FOUND)Printf( “ no pc f n” );else{Printf( “ pc model: %s n” , pc_model);}/* get Printer within the budget–pc_price;*/ rest_budget = total_budgetcolor = “ true ”;EXEC SQL OPEN cursor2 USING :rest_budget, :color;EXEC SQL FETCH cursor2 INTO :printer_model;if(NOT_FOUND) {EXEC SQL CLOSE CURSOR cursor2;color =“ false”;EXEC SQL OPEN cursor2 USING :rest_budget, :color;if(NOT_FOUND)n” );printf(“ no printer found within the budgetelse {EXEC SQL FETCH cursor2 INTO :printer_model;printf(“ printer model: %s n” , printer_model);}}else {printf( “ printer model: %s n” , printer_model);}EXEC SQL CLOSE CURSOR cursor1;EXEC SQL CLOSE CURSOR cursor2;}e)void newPCproduct() {EXEC SQL BEGIN DECLARE SECTION;char pmaker, pmodel[4], ptype[6];float pspeed;int pram, phd, pscreen, pprice;int pcount;EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE stmt1 FROM‘ SELECT COUNT(*) INTO :countFROM PCWHERE MODEL = ?;EXEC SQL PREPARE stmt2 FROM‘ INSERT INTO Product VALUES(?, ?, ?) ’;EXEC SQL PREPARE stmt3 FROM‘ INSERT INTO PC VALUES(?, ?, ?, ?, ?) ’;/* ask user for manufacturer, model, speed, RAM, hard-disk,& price of a new PC*/EXEC SQL EXECUTE stmt1 USING :pmodel;IF (count > 0)Printf( “ Warnning: The PC model already exists n” );ELSE{EXEC SQL EXECUTE stmt2 USING :pmaker, :pmodel, :ptype;EXEC SQL EXECUTE stmt3 UINGNG :pmodel, :pspeed, :pram,:phd, :pprice }}9.3.2a)void largestFirepower() {EXEC SQL BEGIN DECLARE SECTION;char cclass[20], maxFirepowerClass[20];int cnumGuns, cbore;float firepower, maxFirepower;EXEC SQL END DECLARE SECTION;EXEC SQL DECLARE cursor1 CURSOR FORSELECT class, numGuns, bore FROM Classes;EXEC SQL OPEN cursor1;EXEC SQL FETCH FROM cursor1 INTO :cclass, :cnumGuns, :cbore;if(NOT_FOUND) /* print message and exit */ ;maxFirepower = cnumGuns * (power (cbore, 3));strcpy(maxFirepowerClass, cclass);while(1) {EXEC SQL FETCH cursor1 INTO :cclass, :cnumGuns, :cbore;if(NOT_FOUND) break;firepower = cnumGuns * (power (cbore, 3));if( firepower > maxFirepower ){maxFirepower = firepower;strcpy(maxFirepowerClass, cclass);}}printf("Class of maximum firepower :%s\n", maxFirepowerClass);EXEC SQL CLOSE CURSOR cursor1;}b)void getCountry() {EXEC SQL BEGIN DECLARE SECTION;char ibattle[20], iresult[10], ocountry[20];char stmt1[200], stmt2[200];EXEC SQL END DECLARE SECTION;strcpy(stmt1,“ SELECT COUNTRY FROM Classes CWHERE C.class IN (SELECT S.class FROM Ships SWHERE IN (SELECT ship FROM OutcomesWHERE battle = ?))” );Strcpy(stm2,“ SELECT country FROM ClassesWHERE class = ( SELECT MAX(COUNT(class))FROM Ships s, Outcomes oWHERE = s.ship ANDs.result =‘ ?’ )” );EXEC SQL PREPARE query1 FROM stmt1;EXEC SQL PREPARE query2 FROM stmt2;EXEC SQL DECLARE cursor1 CURSOR FOR query1;EXEC SQL DECLARE cursor2 CURSOR FOR query2;/* ask user for battle *//* get countries of the ships involved in the battle */EXEC SQL OPEN cursor1 USING :ibattle;while(!NOT_FOUND) {EXEC SQL FETCH cursor1 INTO :ocountry;if(FOUND)n” , ocoutry);}EXEC SQL CLOSE CURSOR cursor1;/* get the country with the most ships sunk */strcpy(iresult,“ sunk” );EXEC SQL OPEN cursor2 USING :iresult;/* loop for the case there ’ s the same max# of ships sunk */While(!NOT_FOUND) {EXEC SQL FETCH cursor2 INTO :ocountry;If(FOUND)Printf(}/* get the country with the most ships damaged */strcpy(iresult, “ damaged ” ); EXEC SQL OPEN cursor2 USING :iresult;/* loop for the case there ’ s the same max# of ships damaged */While(!NOT_FOUND) {EXEC SQL FETCH cursor2 INTO :ocountry;If(FOUND)Printf(}} c)void addShips() {EXEC SQL BEGIN DECLARE SECTION; char iclass[20], itype[3], icontry[20], iship[20]; int inumGuns, ibore, idisplacement, ilaunched; char stmt1[100], stmt2[100]; EXEC SQL END DECLARE SECTION;strcpy(stmt1,“ INSERT INTO Classes VALUES (?, ?, ?, ?, ?, ?)” );strcpy(stmt2,“ INSERT INTO Ships VALUES (?, ?, ?)” );/* ask user for a class and other info for Classes table */EXEC SQL EXECUTE IMMEDATE :stmt1USING :iclass, :itype, :icontry,:inumGuns, :ibore, :idisplacement;/* ask user for a ship and launched */WHILE(there_is_input){“ country with the most ships damaged: %s, ocountry);“ country with the most ships sunk: %s, ocountry);EXEC SQL EXECUTE IMMEDATE :stmt2USING :iship, :iclass, ilaunched;/* ask user for a ship and launched */}}d)void findError() {EXEC SQL BEGIN DECLARE SECTION;char bname[20], bdate[8], newbdate[8];char sname[20], lyear[4], newlyear[4];char stmt1[100], stmt2[100];EXEC SQL END DECLARE SECTION;strcpy(stmt1, strcpy(stmt2, “ UPDATE Battles SET date = ? WHERE name = ?“ UPDATE Ships SET launched = ? WHERE name = ?” );” );EXEC SQL DECLARE C1 CURSOR FORSelect , b.date, , unchedFROM Battles b, Outcomes o, Ships sWHERE = o.battle ANDo.ship = ANDYEAR(b.date) < unched;EXEC SQL OPEN C1;while(!NOT_FOUND) {EXEC SQL FETCH C1 INTO :bname, :bdate, :sname, :lyear;/* prompt user and ask if a change is needed */if(change_battle){/* get a new battle date to newbdate */EXEC SQL EXECUTE IMMEDATE :stmt1USING :bname, :newbdate;}if(change_ship){/* get a new launched year to newlyear */EXEC SQL EXECUTE IMMEDATE :stmt2USING :sname, :newlyear;}}}9.4.1a)CREATE FUNCTION PresNetWorth(studioName CHAR[15]) RETURNS INTEGER DECLARE presNetWorth INT;BEGINSELECT netWorthINTO presNetWorthFROM Studio, MovieExecWHERE = studioName AND presC# = cert#;RETURN(presNetWorth);END;b)CREATE FUNCTION status(person CHAR(30), addr CHAR(255)) RETURNS INTEGERDECLARE isStar INT;DECLARE isExec INT;BEGINSELECT COUNT(*)INTO isStarFROM MovieStarWHERE = person AND MovieStar.address = addr;SELECT COUNT(*)INTO isExecFROM MovieExecWHERE = person AND MovieExec.address = addr;IF isStar + isExec = 0 THEN RETURN(4) ELSE RETURN(isStar +2*isExec)END IF;END;c)CREATE PROCEDURE twoLongest(IN studio CHAR(15),OUT longest VARCHAR(255),OUT second VARCHAR(255))DECLARE t VARCHAR(255);DECLARE i INT;DECLARE Not_Found CONDITION FOR SQLSTATE = '02000';DECLARE MovieCursor CURSOR FORSELECT title FROM Movies WHERE studioName = studioORDER BY length DESC;BEGINSET longest = NULL;SET second = NULL;OPEN MovieCursor;SET i = 0;mainLoop: WHILE (i < 2) DOFETCH MovieCursor INTO t;IF Not_Found THEN LEAVE mainLoop END IF;SET i = i + 1;END WHILE;CLOSE MovieCursor;END;d)CREATE PROCEDURE earliest120mMovie(IN star CHAR(30),OUT earliestYear INT)DECLARE Not_Found CONDITION FOR SQLSTATE = '02000'; DECLARE MovieCursor CURSOR FORSELECT MIN(year) FROM MoviesWHERE length > 120 ANDtitle IN (SELECT movieTitle FROM StarsInWHERE starName = star);BEGINSET earliestYear = 0;OPEN MovieCursor;FETCH MovieCursor INTO earliestYear;CLOSE MovieCursor;END;e)CREATE PROCEDURE uniqueStar(IN addr CHAR(255),OUT star CHAR(30))BEGINSET star = NULL;IF 1 = (SELECT COUNT(*) FROM MovieStar WHERE address = addr) THENSELECT name INTO star FROM MovieStar WHERE address = addr; END;f)CREATE PROCEDURE removeStar(IN star CHAR(30))BEGINDELETE FROM Movies WHERE title IN(SELECT movieTitle FROM StarsIn WHERE starName = star); DELETE FROM StarsIn WHERE starName = star;DELETE FROM MovieStar WHERE name = star;END;9.4.2a)CREATE FUNCTION closestMatchPC(targetPrice INT) RETURNS CHAR DECLARE closestModel CHAR(4);DECLARE diffSq INT;DECLARE currSq INT;DECLARE m CHAR(4);DECLARE p INT;DECLARE Not_Found CONDITION FOR SQLSTATE '02000'; DECLARE PCCursor CURSOR FORSELECT model, price FROM PC;BEGINSET closestModel = NULL;SET diffSq = -1;OPEN PCCursor;mainLoop: LOOPFETCH PCCursor INTO m, p;IF Not_Found THEN LEAVE mainLoop END IF;SET currSq = (p - targetPrice)*(p - targetPrice);IF diffSq = -1 OR diffSq > currSqTHEN BEGINSET closestModel = m;SET diffSq = currSq;END IF;END LOOP;CLOSE PDCursor;RETURN(closestModel);END;b)CREATE FUNCTION getPrice(imaker CHAR(1), imodel CHAR(4))RETURNS INTEGERDECLARE ptype VARCHAR(10);DECLARE pprice INT;DECLARE Not_Found CONDITION FOR SQLSTATE '02000';BEGINSELECT type INTO ptype FROM ProductWHERE maker = imaker AND model = imodel;IF ptype =‘ pc’ THENSELECT price INTO pprice FROM PCWHERE model = imodel;ELSE IF ptype =‘ laptop’ THENSELECT price INTO pprice FROM LaptopWHERE model = imodel;ELSE IF ptype =‘ printer’ THENSELECT price INTO pprice FROM PrinterWHERE model = imodel;ELSEpprice = NULL;END IF;RETURN (pprice);END;c)CREATE PROCEDURE addPC(IN imodel INT,IN ispeed DECIMAL(3,2),IN iram INT,IN ihd INT,IN iprice INT)DECLARE Already_Exist CONDITION FOR SQLSTATE '02300';BEGININSERT INTO PC VALUES(imodel, ispeed, iram, ihd, iprice); WHILE (Already_Exist) DOSET imodel = imodel + 1;INSERT INTO PC VALUES(imodel, ispeed, iram, ihd, iprice); END WHILE;END;d)CREATE PROCEDURE getNumOfHigherPrice(IN iprice INT,OUT NumOfPCs INT,OUT NumOfLaptops INT,OUT NumOfPrinters INT)BEGINSET NumOfPCs = 0;SET NumOfLaptops = 0;SET NumOfPrinters = 0;SELECT COUNT(*) INTO NumOfPCs FROM PCWHERE price > iprice;SELECT COUNT(*) INTO NumOfLaptops FROM Laptop WHERE price > iprice;SELECT COUNT(*) INTO NumOfPrinters FROM PrinterWHERE price > iprice;END;9.4.3a)CREATE FUNCTION getFirepower(iclass VARCHAR(10)) RETURNS INTEGER DECLARE firepower INT;DECLARE nguns INT;DECLARE nbore INT;BEGINSELECT numGuns, bore INTO nguns, nbore FROM ClassesWHERE class = iclass;SET firepower = nguns * (nbore * nbore * nbore);RETURN(firepower);END;b)CREATE PROCEDURE twoCountriesInBattle(IN ibattle VARCHAR(20),OUT firstCountry VARCHAR(20),OUT secondCountry VARCHAR(20))DECLARE i INT;DECLARE ocountry VARCHAR(20);DECLARE classCursor CURSOR FORSELECT country FROM ClassesWHERE class IN(SELECT class FROM ShipsWHERE name IN(SELECT ship FROM OutcomesWHERE battle = ibattle));BEGINSET firstCountry = NULL;SET secondCountry = NULL;SET i = 0;IF 2 = (SELECT COUNT(*) count FROM ClassesWHERE class IN(SELECT class FROM ShipsWHERE name IN(SELECT ship FROM OutcomesWHERE battle = ibattle)))THENOPEN classCursor;WHILE (i < 2) DOFETCH classCursor INTO ocountry;IF (i = 0) THENSET firstCountry = ocountry;ELSESET secoundCountry = ocountry;END IF;END WHILE;END IF;CLOSE calssCursor;END;c)CREATE PROCEDURE addClass(IN iship VARCHAR(20),IN iclass VARCHAR(20),IN itype CHAR(2),IN icountry VARCHAR(20),IN inumGuns INT,IN ibore INT,IN idisplacement INT)BEGININSERT INTO Classes VALUES(iclass, itype, icountry,inumGuns, ibore, idisplacement); INSERT INTO Ships VALUES(iship, iclass, NULL);END;d)CREATE PROCEDURE checkLaunched(IN ship VARCHAR(20))DECLARE bname VARCHAR(20);BEGINIF EXIST (SELECT INTO bnameFROM Battles b, Outcomes o, Ships sWHERE = o.battle ANDo.ship = ANDYEAR(b.date) < unched)THENUPDATE Ships SET launced = 0 WHERE name = iship;UPDATE Battles SET date = 0 WHERE name = bname; END IF;END9.4.49.5.1a)#include sqlcli.hSQLHENV myEnv;SQLHDBC mycon;SQLHSTMT execStat;SQLRETURN errCode1, errCode2, errCode3;SQLCHAR manf, tempModel[4];SQLFLOAT tempSpeed;SQLINTEGER tempPrice;SQLINTEGER colInfo;Int targetPrice;char modelOfClosest[4];float speedOfClosest;int priceOfClosest;/* ask user for target price and read the answer into variabletargetPrice*/errCode1 = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &myEnv);if(errCode1) {printf( ” Error for SQL_HANDLE_ENV. n” );exit(1);}errCode2 = SQLAllocHandle(SQL_HANDLE_DBC, myEnv, &myCon);if(errCode2) {printf( ” Error for SQL_ HANDLE_DBC. n” );exit(1);}errCode3 = SQLAllocHandle(SQL_HANDLE_STMT, myCon, &execStat);if(errCode3) {printf( ” Error for SQL_ HANDLE_STMT. n” );exit(1);}SQLExecDirect(execStat, “ SELECT model, price, speed FROM PC ” , SQL_NTS);SQLBindCol(execStat, 1, SQL_CHAR, tempModel,sizeof(tempModel), &colInfo);SQLBindCol(execStat, 2, SQL_INTEGER, tempPrice,sizeof(tempPrice), &colInfo);SQLBindCol(execStat, 3, SQL_FLOAT, tempSpeed,sizeof(tempSpeed), &colInfo);priceOfClosest = NULL;while(SQLFetch(execStat) != SQL_NO_DATA) {if( /* the 1st fetch or tempPrice closer to targetPrice */modelOfClosest = tempModel;priceOfClosest = tempPrice;speedOfClosest = tempSpeed;}}/* Now, modelOfClosest is the model whose price is closest totarget. We must get its manufacturer with a single-row select*/if (priceOfClosest == NULL ) /* no data fetched *//* print error message and exit */SQLPrepare (execStat,“ SELECT maker FROM Product WHERE model = ? ” , SQL_NTS); SQLBindParameter(execStat, 1,⋯,modelOfClosest,⋯);SQLExecute(execStat);SQLBindCol(execStat, 1, SQLCHAR, &manf, sizeof(manf), &colInfo);/* print manf */b)#include sqlcli.hSQLHENV myEnv;SQLHDBC mycon;SQLHSTMT execStat;SQLRETURN errCode1, errCode2, errCode3;SQLCHAR model[4], maker;SQLFLOAT minSpeed;SQLINTEGER minRam, minHd, minScreen;SQLFLOAT speed;SQLINTEGER ram, hd, screen;SQLINTEGER colInfo;/* ask user for minimum speed, ram, hd size, and screen size */errCode1 = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &myEnv);if(errCode1) {printf( ” Error for SQL_HANDLE_ENV. n” );exit(1);}errCode2 = SQLAllocHandle(SQL_HANDLE_DBC, myEnv, &myCon);if(errCode2) {printf( ” Error for SQL_ HANDLE_DBC. n” );exit(1);}errCode3 = SQLAllocHandle(SQL_HANDLE_STMT, myCon, &execStat);if(errCode3) {printf( ” Error for SQL_ HANDLE_STMT. n” );exit(1);}SQLPrepare(execStat,“ SELECT model, speed, ram, hd, screen, price, maker“ FROM Laptop l, Product p”||“ WHERE speed >= ? AND ” ||“ ram >= ? AND”||“ hd >= ? AND”||“ screen >= ? AND”||“ l.model = p.model”,”||SQL_NTS);SQLBindParameter(execStat, 1, SQL_FLOAT, ⋯ , minSpeed, ⋯ ); SQLBindParameter (execStat, 2, SQL_INTEGER, ⋯ , minRam, ⋯ );SQLBindParameter (execStat, 3, SQL_ SQLBindParameter (execStat, 4, SQL_ INTEGER,INTEGER,⋯ , minHd, ⋯ );⋯ , minScreen, ⋯ );SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, model, sizeof(model), &colInfo); SQLBindCol(execStat, 2, SQL_FLOAT, speed,sizeof(speed), &colInfo);SQLBindCol(execStat, 3, SQL_INTEGER, ram,sizeof(ram), &colInfo);SQLBindCol(execStat, 4, SQL_INTEGER, hd,sizeof(hd), &colInfo);SQLBindCol(execStat, 5, SQL_INTEGER, screen,sizeof(screen), &colInfo);SQLBindCol(execStat, 6, SQL_INTEGER, price,sizeof(price), &colInfo);SQLBindCol(execStat, 7, SQL_CHAR, maker,sizeof(maker), &colInfo);while(SQLFetch(execStat) != SQL_NO_DATA) {if( FOUND )/* print fetched info */}c)#include sqlcli.hSQLHENV myEnv;SQLHDBC mycon;SQLHSTMT execStat;SQLRETURN errCode1, errCode2, errCode3;SQLCHAR maker, model[4], type[10], color[6];SQLFLOAT speed;SQLINTEGER ram, hd, screen, price;SQLINTEGER colInfo;/* ask user for minimum speed, ram, hd size, and screen size */errCode1 = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &myEnv); if(errCode1) {printf( ” Error for SQL_HANDLE_ENV. n” );exit(1);}errCode2 = SQLAllocHandle(SQL_HANDLE_DBC, myEnv, &myCon);if(errCode2) {printf( ” Error for SQL_ HANDLE_DBC.n” );exit(1);}errCode3 = SQLAllocHandle(SQL_HANDLE_STMT, myCon, &execStat);if(errCode3) {printf( ” Error for SQL_ HANDLE_STMT.n” );exit(1);}/* get PCs made by the manufacturer */SQLPrepare(execStat,“ SELECT * FROM PC WHERE model IN ( ” ||“ SELECT model FROM Product ” ||“ WHERE maker = ? AND ” ||“ type = ‘ pc’”, SQL_NTS);SQLBindParameter(execStat, 1, SQL_CHAR,⋯, maker,⋯); SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, model, sizeof(model), &colInfo); SQLBindCol(execStat, 2, SQL_FLOAT, speed,sizeof(speed), &colInfo);SQLBindCol(execStat, 3, SQL_INTEGER, ram,sizeof(ram), &colInfo);SQLBindCol(execStat, 4, SQL_INTEGER, hd,sizeof(hd), &colInfo);SQLBindCol(execStat, 5, SQL_INTEGER, price,sizeof(price), &colInfo);while(SQLFetch(execStat) != SQL_NO_DATA) {if( FOUND )/* print fetched info */}/* get Laptops made by the manufacturer */SQLPrepare(execStat,“ SELECT * FROM Laptop WHERE model IN ( ” ||“ SELECT model FROM Product ” ||“ WHERE maker = ? AND ” ||“ type = ‘ laptop ’”, SQL_NTS);SQLBindParameter(execStat, 1, SQL_CHAR,⋯, maker,⋯); SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, model, sizeof(model), &colInfo);SQLBindCol(execStat, 2, SQL_FLOAT, speed,sizeof(speed), &colInfo);SQLBindCol(execStat, 3, SQL_INTEGER, ram,sizeof(ram), &colInfo);SQLBindCol(execStat, 4, SQL_INTEGER, hd,sizeof(hd), &colInfo);SQLBindCol(execStat, 5, SQL_INTEGER, screen,sizeof(screen), &colInfo);SQLBindCol(execStat, 6, SQL_INTEGER, price,sizeof(price), &colInfo);while(SQLFetch(execStat) != SQL_NO_DATA) {if( FOUND )/* print fetched info */}/* get Printers made by the manufacturer */SQLPrepare(execStat,“ SELECT * FROM Printer WHERE model IN (”||“ SELECT model FROM Product”||“ WHERE maker = ? AND ” ||“ type =‘printer’”,SQL_NTS);SQLBindPara meter(execStat, 1, SQL_CHAR,⋯, maker,⋯);SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, model, sizeof(model), &colInfo);SQLBindCol(execStat, 2, SQL_CHAR, color, sizeof(color), $colInfo);SQLBindCol(execStat, 3, SQL_CHAR, type, sizeof(type), $colInfo);SQLBindCol(execStat, 4, SQL_INTEGER, price, sizeof(price), &colInfo);d)#include sqlcli.hSQLHENV myEnv;SQLHDBC mycon;SQLHSTMT execStat;SQLRETURN errCode1, errCode2, errCode3;SQLINTEGER total_budget, rest_budget, pc_price, printer_price;SQLCHAR pc_model[4], printer_model[4], color[6];SQLFLOAT min_speed;errCode1 = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &myEnv);if(errCode1) {printf( ” Error for SQL_HANDLE_ENV.n” );exit(1);}errCode2 = SQLAllocHandle(SQL_HANDLE_DBC, myEnv, &myCon);if(errCode2) {printf( ” Error for SQL_ HANDLE_DBC.n” );exit(1);}errCode3 = SQLAllocHandle(SQL_HANDLE_STMT, myCon, &execStat);if(errCode3) {printf( ” Error for SQL_ HANDLE_STMT. n” );exit(1);}SQLPrepare(execStat,“SELECT model, price FROM PCWHERE speed >= ? AND price <= ? ORDERBY price ”,SQL_NTS);/* ask user for budget & the minimum speed of pc *//* get the cheapest PC of the minimum speed */SQLBindParameter(execStat, 1, SQL_FLOAT , ⋯ ,min_speed , ⋯ ); SQLBindParameter(execStat, 2, SQL_INTEGER, ⋯ , total_budget, ⋯ );SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, pc_model, sizeof(pc_model),&colInfo);SQLBindCol(execStat, 2, SQL_INGETER, pc_price,sizeof(pc_price),&colInfo);SQLFetch(execStat);if (NOT_FOUND) {p rintf(“no pc found within the budget n” );}else {p rintf( “ pc model: %s n” , pc_model);}/* get Printer within the budget */–pc_price;rest_budget = total_budgetcolor =“true”;SQLPrepare(execStat,“SELECT model, price FROM PrinterWHERE price <= ? AND color = ?ORDER BY price ” , SQL_NTS);SQLBindParameter(execStat, 1, SQL_INTEGER , ⋯ , rest_budget , ⋯ ); SQLBindParameter(execStat, 2, SQL_CHAR, ⋯ , color , ⋯ );SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, print_model,sizeof(print_model),&colInfo);SQLBindCol(execStat, 2, SQL_INGETER, print_price,sizeof(print_price),&colInfo);SQLFetch(execStat);if(NOT_FOUND) {color =“false”;SQLBindParameter(execStat, 1, SQL_INTEGER,⋯, rest_budget,⋯);SQLBindParameter(execStat, 2, SQL_CHAR,⋯, color,⋯);SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_CHAR, print_model,sizeof(print_model),&colInfo);SQLBindCol(execStat, 2, SQL_INGETER, print_price,sizeof(print_price),&colInfo);SQLFetch(execStat);if(NOT_FOUND)printf( “ no printer found within the budget n” );elseprintf( “ printer model: %s n” , printer_model);}elseprintf( “ printer model: %s n” , printer_model);}e)#include sqlcli.hSQLHENV myEnv;SQLHDBC mycon;SQLHSTMT execStat;SQLRETURN errCode1, errCode2, errCode3;SQLCHAR pmodel[4], pmaker, ptype[6];SQLFLOAT pspeed;SQLINTEGER pram, phd, pscreen, pprice, count;SQLINTEGER colInfo;/* ask user for minimum speed, ram, hd size, and screen size */errCode1 = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &myEnv);if(errCode1) {printf( ” Error for SQL_HANDLE_ENV.n” );exit(1);}errCode2 = SQLAllocHandle(SQL_HANDLE_DBC, myEnv, &myCon);if(errCode2) {printf( ” Error for n” );exit(1);}errCode3 = SQLAllocHandle(SQL_HANDLE_STMT, myCon, &execStat);if(errCode3) {printf( ” Error for SQL_ HANDLE_STMT. n” );exit(1);}/* ask user for manufacturer, model, speed, RAM, hard-disk, *//* & price of a new PC */SQLPrepare(execStat,“ SELECT COUNT(*) FROM PC WHERE model = ?”, SQL_NTS);SQLBindParameter(execStat, 1, SQL_CHAR,⋯, pmodel,⋯);SQLExecute(execStat);SQLBindCol(execStat, 1, SQL_INTEGER, count, sizeof(count), &colInfo);SQLFetch(execStat);if (count >0){ Printf( “ Warnning: The PC model already exists n” ); }else {” , SQLPrepare(execStat,“ INSERT INTO Product VALUES(?, ?, ?)SQL_NTS);SQLBindParame ter(execStat, 1, SQL_CHAR,⋯, pmaker,⋯);SQLBindParameter(execStat, 2, SQL_CHAR,⋯, pmodel,⋯);SQLBindParameter(execStat, 3, SQL_CHAR,⋯, ptype,⋯); SQLExecute(execStat);” , SQLPrepare(execStat,“ INSERT INTO PC VALUES(?, ?, ?, ?, ?)SQL_NTS);SQLBindParameter(execStat, 1, SQL_CHAR,⋯, pmodel,⋯);SQLBindParameter(execStat, 2, SQL_FLOAT,⋯, pspeed,⋯);SQLBindParameter(execStat, 3, SQL_INTEGER,⋯, pram,⋯); SQLBindParameter(e xecStat, 4, SQL_INTEGER,⋯, phd,⋯);SQLBindParameter(execStat, 5, SQL_INTEGER,⋯, pprice,⋯); SQLExecute(execStat);}9.5.2a)#include sqlcli.hSQLHENV myEnv;SQLHDBC mycon;SQLHSTMT execStat;SQLRETURN errCode1, errCode2, errCode3;SQLCHAR cclass[20], maxFirepowerClass[20];SQLFLOAT firepower, maxFirepower;SQLINTEGER cnumGuns, cbore;。
第9章数据库恢复技术1.试述事务的概念及事务的4 个特性。
答:事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。
事务具有4 个特性:原子性(Atomicity )、一致性(consistency )、隔离性( Isolation )和持续性(Durability )。
这4 个特性也简称为ACID 特性。
原子性:事务是数据库的逻辑工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性:一个事务的执行不能被其他事务干扰。
即一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
持续性:持续性也称永久性(Perfnanence ) ,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
接下来的其他操作或故障不应该对其执行结果有任何影响。
2 .为什么事务非正常结束时会影响数据库数据的正确性,请列举一例说明之。
答:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。
例如某工厂的库存管理系统中,要把数量为Q 的某种零件从仓库1 移到仓库2 存放。
则可以定义一个事务T , T 包括两个操作;Ql = Ql 一Q , Q2= Q2 + Q。
如果T 非正常终止时只做了第一个操作,则数据库就处于不一致性状态,库存量无缘无故少了Q 。
3 .数据库中为什么要有恢复子系统?它的功能是什么?答:因为计算机系统中硬件的故障、软件的错误、操作员的失误以及恶意的破坏是不可避免的,这些故障轻则造成运行事务非正常中断,影响数据库中数据的正确性,重则破坏数据库,使数据库中全部或部分数据丢失,因此必须要有恢复子系统。
恢复子系统的功能是:把数据库从错误状态恢复到某一已知的正确状态(亦称为一致状态或完整状态)。
4 .数据库运行中可能产生的故障有哪几类?哪些故障影响事务的正常执行?哪些故障破坏数据库数据?答:数据库系统中可能发生各种各样的故障,大致可以分以下几类:(1)事务内部的故障;(2)系统故障;(3)介质故障;(4)计算机病毒。
事务故障、系统故障和介质故障影响事务的正常执行;介质故障和计算机病毒破坏数据库数据。
5 .数据库恢复的基本技术有哪些?答:数据转储和登录日志文件是数据库恢复的基本技术。
当系统运行过程中发生故障,利用转储的数据库后备副本和日志文件就可以将数据库恢复到故障前的某个一致性状态。
6 .数据库转储的意义是什么?试比较各种数据转储方法。
答:数据转储是数据库恢复中采用的基本技术。
所谓转储即DBA 定期地将数据库复制到磁带或另一个磁盘上保存起来的过程。
当数据库遭到破坏后可以将后备副本重新装入,将数据库恢复到转储时的状态。
静态转储:在系统中无运行事务时进行的转储操作,如上图所示。
静态转储简单,但必须等待正运行的用户事务结束才能进行。
同样,新的事务必须等待转储结束才能执行。
显然,这会降低数据库的可用性。
动态转储:指转储期间允许对数据库进行存取或修改。
动态转储可克服静态转储的缺点,它不用等待正在运行的用户事务结束,也不会影响新事务的运行。
但是,转储结束时后援副本上的数据并不能保证正确有效。
因为转储期间运行的事务可能修改了某些数据,使得后援副本上的数据不是数据库的一致版本。
为此,必须把转储期间各事务对数据库的修改活动登记下来,建立日志文件( 109 file )。
这样,后援副本加上日志文件就能得到数据库某一时刻的正确状态。
转储还可以分为海量转储和增量转储两种方式。
海量转储是指每次转储全部数据库。
增量转储则指每次只转储上一次转储后更新过的数据。
从恢复角度看,使用海量转储得到的后备副本进行恢复一般说来更简单些。
但如果数据库很大,事务处理又十分频繁,则增量转储方式更实用更有效。
7 .什么是日志文件?为什么要设立日志文件?答:(1)日志文件是用来记录事务对数据库的更新操作的文件。
(2)设立日志文件的目的是:进行事务故障恢复;进行系统故障恢复;协助后备副本进行介质故障恢复。
8 .登记日志文件时为什么必须先写日志文件,后写数据库?答:把对数据的修改写到数据库中和把表示这个修改的日志记录写到日志文件中是两个不同的操作。
有可能在这两个操作之间发生故障,即这两个写操作只完成了一个。
如果先写了数据库修改,而在运行记录中没有登记这个修改,则以后就无法恢复这个修改了。
如果先写日志,但没有修改数据库,在恢复时只不过是多执行一次UNDO 操作,并不会影响数据库的正确性。
所以一定要先写日志文件,即首先把日志记录写到日志文件中,然后写数据库的修改。
9 .针对不同的故障,试给出恢复的策略和方法。
(即如何进行事务故障的恢复?系统故障的恢复?介质故障恢复?)答:事务故障的恢复:事务故障的恢复是由DBMS DBMs 执行恢复步骤是:自动完成的,对用户是透明的。
(1)反向扫描文件日志(即从最后向前扫描日志文件),查找该事务的更新操作;(2)对该事务的更新操作执行逆操作,即将日志记录中“更新前的值”写入数据库;(3)继续反向扫描日志文件,做同样处理;(4)如此处理下去,直至读到此事务的开始标记,该事务故障的恢复就完成了。
系统故障的恢复:系统故障可能会造成数据库处于不一致状态:一是未完成事务对数据库的更新可能已写入数据库;二是已提交事务对数据库的更新可能还留在缓冲区,没来得及写入数据库。
因此恢复操作就是要撤销(UNDO )故障发生时未完成的事务,重做(REDO )已完成的事务。
系统的恢复步骤是:(1)正向扫描日志文件,找出在故障发生前已经提交的事务队列(REDO 队列)和未完成的事务队列(uNDO 队列)。
(2)对撤销队列中的各个事务进行UNDO 处理。
进行UNDO 处理的方法是,反向扫描日志文件,对每个UNDO 事务的更新操作执行逆操作,即将日志记录中“更新前的值”Before Image )写入数据库。
( 3 )对重做队列中的各个事务进行REDO 处理。
进行REDO 处理的方法是:正向扫描日志文件,对每个REDO 事务重新执行日志文件登记的操作。
即将日志记录中“更新后的值”Afte , Image )写入数据库。
介质故障的恢复:介质故障是最严重的一种故障。
恢复方法是重装数据库,然后重做已完成的事务。
具体过程是:( 1 ) DBA 装入最新的数据库后备副本(离故障发生时刻最近的转储副本), 使数据库恢复到转储时的一致性状态;( 2 ) DBA 装入转储结束时刻的日志文件副本;( 3 ) DBA 启动系统恢复命令,由DBMS 完成恢复功能,即重做已完成的事务。
10 .什么是检查点记录?检查点记录包括哪些内容?答:检查点记录是一类新的日志记录。
它的内容包括:①建立检查点时刻所有正在执行的事务清单②这些事务的最近一个日志记录的地址。
11 .具有检查点的恢复技术有什么优点?试举一个具体的例子加以说明。
答答:利用日志技术进行数据库恢复时,恢复子系统必须搜索日志,确定哪些事务需要REDO ,哪些事务需要uNDO 。
一般来说,需要检查所有日志记录。
这样做有两个问题:一是搜索整个日志将耗费大量的时间;二是很多需要REDO 处理的事务实际上已经将它们的更新操作结果写到数据库中了,恢复子系统又重新执行了这些操作,浪费了大量时间。
检查点技术就是为了解决这些问题。
在采用检查点技术之前,恢复时需要从头扫描日志文件,而利用检查点技术只需要从T 。
开始扫描日志,这就缩短了扫描日志的时间。
事务Tl 的更新操作实际上已经写到数据库中了,进行恢复时没有必要再REDO 处理,采用检查点技术做到了这一点。
12 .试述使用检查点方法进行恢复的步骤。
答:(1)从重新开始文件(见第11 题的图)中找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录。
(2)由该检查点记录得到检查点建立时刻所有正在执行的事务清单ACTIVE 一LIST 。
这里建立两个事务队列:1 ) UNDO 一LIST :需要执行undo 操作的事务集合;2 ) REDO 一LIST :需要执行redo 操作的事务集合。
把ACTIVE 一LIST 暂时放入UNDO 一LIST 队列,REDO 队列暂为空。
3 )从检查点开始正向扫描日志文件:①如有新开始的事务T * ,把T *暂时放入uNDO 一LlsT 队列;②如有提交的事务毛,把毛从UNDO 一LIST 队列移到REDO 一LIST 队列,直到日志文件结束;4 )对UNDO 一LIST 中的每个事务执行UNDO 操作,对REDO 一LIST 中的每个事务执行REDO 操作。
13 .什么是数据库镜像?它有什么用途?答:数据库镜像即根据DBA 的要求,自动把整个数据库或者其中的部分关键数据复制到另一个磁盘上。
每当主数据库更新时,DBMS 自动把更新后的数据复制过去,即DBMS 自动保证镜像数据与主数据的一致性。
数据库镜像的用途有:一是用于数据库恢复。
当出现介质故障时,可由镜像磁盘继续提供使用,同时DBMS 自动利用镜像磁盘数据进行数据库的恢复,不需要关闭系统和重装数据库副本。
二是提高数据库的可用性。
在没有出现故障时,当一个用户对某个数据加排它锁进行修改时,其他用户可以读镜像数据库上的数据,而不必等待该用户释放锁。