课程教材:《数据库系统概论》 王珊 萨师煊
本文是自己根据学校的课程内容整理的数据库期末复习资料,可能不同学校的教学内容不同,所以难免会有内容的遗漏,同时由于时间紧迫,难免会有笔误或知识性错误之处,欢迎斧正,希望能帮到有需要的同学。
定义:data 记录事物情况的物理符号,是数据库中储存的基本对象
数据的含义成为语义,数据与其语义是不可分的
定义:数据库(Database,简称DB)是长期储存在计算机内、有组织的、可共享的大量数据的集合。以文件方式存储
基本特征:数据按一定的数据模型组织、描述储存可为各种用户共享、冗余度较小、数据独立性较高易扩展
定义:简称DBMS是位于用户与操作系统之间的一层数据管理软件.是基础软件,是一个大型复杂的软件系统
用途:科学地组织和存储数据、高效地获取和维护数据
主要功能: 数据定义功能(提供DDL 定义数据对象)、数据组织、存储和管理、数据操纵(DML实现增删改查)、数据库的事务管理和运行管理(安全性、完整性)
定义: 简称DBS 在计算机系统中引入数据库后的系统构成
构成: 数据库、数据库管理系统(以及开发工具)、应用操作系统、数据库管理员
具体构成有四大要素:硬件(计算机硬件环境包括网络、存储、I/O、主机)、软件(OS、DBMS、数据库应用程序等,DBMS是数据库系统的核心。)、数据库(数据集合)、数据库系统的有关人员(最终用户、数据库应用系统开发人员和数据库管理员(DBA))
### 1.2.3数据独立性高
DBMS提供的数据控制功能
(1)数据的安全性(Security)保护
保护数据,以防止不合法的使用造成的数据的泄密和破坏。
(2)数据的完整性(Integrity)检查
将数据控制在有效的范围内,或保证数据之间满足一定的关系。
(3)并发(Concurrency)控制
对多用户的并发操作加以控制和协调,防止相互干扰而得到错误的结果。
(4)数据库恢复(Recovery)
将数据库从错误状态恢复到某一已知的正确状态。
定义:数据模型是现实世界的模拟
满足三方面要求:能比较真实地模拟现实世界
容易为人所理解
便于在计算机上实现
也称信息模型,它是按用户的观点来对数据和信息建模,用于数据库设计。
逻辑模型主要包括网状模型、层次模型、关系模型、面向对象模型等,按计算机系统的观点对数据建模,用于DBMS实现。
物理模型是对数据最底层的抽象,描述数据在系统内部的表示方式和存取方法,在磁盘或磁带上的存储方式和存取方法
数据结构:描述数据库的组成对象,以及对象之间的联系
数据操作:对数据库中各种对象(型)的实例(值)允许执行的操作及有关的操作规则 包括增删改查
完整性约束条件:是一组完整性规则的集合。给定的数据模型中数据及其联系所具有的制约和储存规则
用以限定符合数据模型的数据库状态以及状态的变化,以保证数据的正确、有效、相容。
客观存在并可相互区别的事物称为实体。
可以是具体的人、事、物或抽象的概念。
实体所具有的某一特性称为属性。
一个实体可以由若干个属性来刻画。
唯一标识实体的属性集称为码。
属性的取值范围称为该属性的域。
用实体名及其属性名集合来抽象和刻画同类实体称为实体型
同一类型实体的集合称为实体集
现实世界中事物内部以及事物之间的联系在信息世界中反映为实体内部的联系和实体之间的联系。
实体内部的联系通常是指组成实体的各属性之间的联系
实体之间的联系通常是指不同实体集之间的联系
如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之联系,反之亦然,则称实体集A与实体集B具有一对一联系,记为1:1
eg:
一个班级只有一个正班长
一个班长只在一个班中任职
如果对于实体集A中的每一个实体,实体集B中
有n个实体(n≥0)与之联系,反之,对于实体
集B中的每一个实体,实体集A中至多只有一个
实体与之联系,则称实体集A与实体集B有一对
多联系,记为1:n
eg:
一个班级中有若干名学生,
每个学生只在一个班级中学习
如果对于实体集A中的每一个实体,实体集B中
有n个实体(n≥0)与之联系,反之,对于实
体集B中的每一个实体,实体集A中也有m个实
体(m≥0)与之联系,则称实体集A与实体B
具有多对多联系,记为m:n
eg:
一门课程同时有若干个学生选修
一个学生可以同时选修多门课程
需要在n方(即1对多关系的多方)实体表中增加一个属性,将对方的关键字作为外部关键字处理。
例: 系与学生之间的一对多联系:
学生(学号,姓名,年龄,性别,系号,年级)
系 (系号,系名,办公地点)
各自增加对方的关键字作为外部关键字
例 系与系主任间的一对一联系
需要单独建立一个关系模式,分别用两个实体的关键字作为外部关键字。
例 学生与课程之间的多对多联系:
学生(学号,姓名,年龄,性别,系号,年级)
课程(课程号,课程名,学分)
选修(学号,课程号,成绩)
数据操作是集合操作,操作对象和操作结果都是关系
查询
插入
删除
更新
数据操作是集合操作,操作对象和操作结果都是关系,即若干元组的集合
存取路径对用户隐蔽,用户只要指出“干什么”,不必详细说明“怎么干”
从数据库管理系统角度看,数据库系统通常采用三级模式结构,是数据库系统内部的系统结构
从数据库最终用户角度看(数据库系统外部的体系结构) ,数据库系统的结构分为:
型(Type)
对某一类数据的结构和属性的说明
eg:学生记录型:
(学号,姓名,性别,系别,年龄,籍贯)
值(Value):是型的一个具体赋值
eg:一个记录值:
(900201,李明,男,计算机,22,江苏)
模式(Schema)
数据库逻辑结构和特征的描述
是型的描述
反映的是数据的结构及其联系
模式是相对稳定的
实例(Instance)
模式的一个具体值
反映数据库某一时刻的状态
同一个模式可以有很多实例
实例随数据库中的数据的更新而变动
eg:例如:在学生选课数据库模式中,包含学生记录、课程记录和学生选课记录
2003年的一个学生数据库实例,包含:
– 2003年学校中所有学生的记录
– 学校开设的所有课程的记录
– 所有学生选课的记录
2002年度学生数据库模式对应的实例与 2003年度学生数据库模式对应的实例是不同的
模式(Schema)(逻辑模式):数据库中全体数据的逻辑结构和特征的描述
所有用户的公共数据视图,综合了所有用户的需求
一个数据库只有一个模式
是数据库系统模式结构的中间层
与数据的物理存储细节和硬件环境无关
与具体的应用程序、开发工具及高级程序设计语言无关
外模式(External Schema)(子模式或用户模式) 数据库用户(包括应用程序员和最终用户)使用的局部数据的逻辑结构和特征的描述
–外模式通常是模式的子集
–一个数据库可以有多个外模式。反映了不同的用户的应用需求、看待数据的方式、对数据保密的要求
–对模式中同一数据,在外模式中的结构、类型、长度、保密级别等都可以不同
–同一外模式也可以为某一用户的多个应用系统所使用
–但一个应用程序只能使用一个外模式
内模式(Internal Schema)(存储模式)
三级模式是对数据的三个抽象级别
二级映象在DBMS内部实现这三个抽象层次的联系和转换
保证了数据库外模式的稳定性
从底层保证了应用程序的稳定性,除非应用需求本身发生变化,否则应用程序一般不需要修改
1.综合统一
集数据定义语言DDL、数据操纵语言DML数据控制语言DCL于一体。
2.高度非过程化
3.面向集合的操作方式
4.以同一种语法结构提供两种使用方式
5.语言简洁,易学易用
Create table/view/index
Alter table
Drop table
Select…from…
Insert into
Delete from
Update
具体增删改查操作语法参考详细的SQL笔记.不在此赘述
1.需求分析:需求收集和分析
2.概念结构设计:设计概念结构
3.逻辑结构设计:设计逻辑结构 数据模型优化
4.数据库物理设计:设计物理结构 评价设计、性能预测
5.数据库实施:物理实现
试运行
6.数据库运行和维护:使用维护、数据库
一、需求分析的任务
(1)信息要求
(2)处理要求
(3)功能要求
(4)企业环境特征
二、需求分析的方法
1、概念结构
主要特点:
(1)能反映现实、满足处理要求
(2)易于理解
(3)易于更改
(4)易于数据模型转换
概念结构设计任务:
将用户需求抽象为概念模型 (E-R图)。
2、概念结构设计的方法
自顶向下
自底向上
逐步扩张
混合策略
任务:将基本E-R模型转换为DBMS所支持的数据模型。
关系型逻辑结构设计的步骤:
转换的一般原则:
(1)一个实体型转换为一个关系模式。
(2)一个1:1联系可转换为一个独立的关系模式,也可与任一端对应的关系模式合并。
(3)一个1:n联系可转换为一个独立的关系模式,也可与n端对应的关系模式合并。
(4)一个m: n联系转换为一个关系模式。
(5)三个或三个以上实体间的多元联系可转换为一个关系模式。
(6) 相同码的关系模式可合并集。
码原则:
具有相同码的关系模式可以合并。
数据库物理设计:
为给定的数据模型选取一个最适合应用要求的物理结构的过程。
步骤:确定DB的物理结构 (存取方法、存储结构)
评价结构的时、空效率(取决于DBMS)
目标:设计优化的物理DB结构,使得响应时间短、空间利用率高、事务吞吐率大。
设计准备:
1、分析要运行的事务,获得选择物理设计所需要的参数。
2、了解所用RDBMS的存取方法和存储结构。
如:对数据库查询事务,需得到:
查询的关系:
查询条件所涉及的属性;
连接条件所涉及的属性;
查询的投影属性。
数据库实施主要任务:
(1)定义数据库结构
(2)组织数据入库
(3)编制与调试应用程序
(4)数据库试运行。
数据库维护主要任务:
(1)数据的转储与恢复
(2)数据库的安全性、完整性控制
(3)数据库的性能监督、分析和改造
(4)数据库的重组织与重构造
重点:关系代数
查询:选择、投影、连接、除、并、交、差
数据更新:插入、删除、修改
选择、投影、并、差、笛卡尔积是五种基本操作
关系操作的特点
集合操作方式:操作的对象和结果都是集合,一次一集合的方式
定义:若属性A是基本关系R的主属性,则A不可取空值
也就是主键不能为空
若属性或属性组F是基本关系R的外码,它与基本关系S的主码Ks相对应(基本关系R和S不一定是不同的关系),则对于R中每个元组在F上的值必须为:取空值(F的每个属性值均为空)或者等于S中某个元组的主码值。
也就是 外码只能是空值或对应参照表里确实存在的值
定义两个关系R和S:具有相同的目n(两个关系都有n个属性),相同的属性来自同一个域
R∪S
仍为n目关系,由属于R或属于S的元组组成
R∪S = {t|t∈R ∨ t∈ S}
定义两个关系R和S:具有相同的目n(两个关系都有n个属性),相同的属性来自同一个域
R-S
仍为n目关系,由属于R而不属于S的所有元组组成
R - S = {t|t∈R∧t∉S}
定义两个关系R和S:具有相同的目n(两个关系都有n个属性),相同的属性来自同一个域
R∩S
仍为n目关系,由既属于R又属于S的元组构成
R∩S = {t|t∈R∧t∈S}
R∩S = R - (R-S)
R:n目关系,k1个元组
S:m目关系,k2个元组
RXS:
列:(n+m)列元组的集合
元组的前n列是关系R的一个元组
后m列是关系S的一个元组
行:k1*k2个元组
选择运算针对于行
基本形式:条件写在σ右下角 选择的表写在括号内
被除表的某一属性列的值能够对应在被除表中的所有属性以及在除表中也能意义对应则保留为结果列值
非授权用户对数据库的恶意存取和破坏
解决方法:身份鉴别、存取控制、视图
数据库中重要或敏感的数据被泄露
解决方法:强制存取控制、数据加密存储和传输入
安全环境的脆弱性
解决方法:建立一套完整的安全标准
'用户标识和鉴定'
'存取控制'
'视图'
'审计'
'密码存储'
系统提供的最外层安全保护措施
用户标识:由用户名和用户标识号组成
用户身份鉴别方法:口令
用户名和口令易被窃取
存取控制机制组成
用户权限定义和合法权检查机制一起组成了 DBMS的存取控制子系统
用存取控制方法
自主存取控制(Discretionary Access Control ,简称DAC)
用户对不同数据对象的有不同的存取权限。
不同用户对统一对象的存取权限也不同
用户可将其用户的存取权限授权给其他用户
C2级
灵活
强制存取控制(Mandatory Access Control,简称 MAC)
GRANT<权限> [,<权限>]...
[ON <对象类型> <对象名>]
TO <用户>[,<用户>]...
WITH GRANT OPTION];--可以转授权限,但不允许循环授权
使用REVOKE语句可以收回授予的权限
REVOKE <权限>[,<权限>]...
[ON <对象类型> <对象名>]
FROM <用户>[,<用户>]...;
数据库角色:被命名的一组与数据库操作相关的权限
角色的创建
CREATE ROLE <角色名>
GRANT <权限>[,<权限>]…
ON <对象类型>对象名
TO <角色>[,<角色>]…
GRANT <角色1>[,<角色2>]…
TO <角色3>[,<用户1>]…
[WITH ADMIN OPTION] --可以转授
REVOKE <权限>[,<权限>]…
ON <对象类型> <对象名>
FROM <角色>[,<角色>]…
对系统控制下的所有主客体实施强制存取控制策略,可解决自主存取控制下可能存在数据的“无意泄露”,为数据本身添加安全性标记,提高安全性。
主体是系统中的活动实体
客体是系统中的被动实体,是受主体操纵的
敏感度标记(Label)
强制存取控制规则
仅当主体的许可证级别大于或等于客体的密级时,该主体才能读取相应的客体
仅当主体的许可证级别等于客体的密级时,该主体才能写相应的客体
把要保密的数据对无权存取这些数据的用户隐藏起来,对数据提供一定程度的安全保护
语法:
CREATE VIEW [视图名]
AS
[查询语句]
审计日志(Audit Log)
将用户对数据库的所有操作记录在上面
审计分为
用户级审计
系统级审计
AUDIT语句:设置审计功能
防止数据库中数据在存储和传输中失密的有效手段
规则1:任何查询至少要涉及N(N足够大)个以上的记录
规则2:任意两个查询的相交数据项不能超过M个
规则3:任一用户的查询次数不能超过1+(N-2)/M
把SQL语言嵌入到某种高级语言中使用的SQL语言称为嵌入式SQL(Embedded SQL),而嵌入SQL的高级语言称为主语言或宿主语言。
用EXEC SQL INCLUDE SQLCA定义;有存放每次执行SQL语句后返回代码的变量SQLCODE;预定义的常量SUCCESS,表示执行成功;应用程序测试SQLCODE的值是否为SUCCESS(0),并做相应处理。
输入主变量:由应用程序对其赋值,SQL语句引用
输出主变量:由SQL语句赋值或设置状态信息,返回给应用程序
指示变量:一个主变量可以附带一个指示变量,指示变量是整型变量,用来“指示”所指主变量的值或条件。
BEGIN DECLARE SECTION
....... (说明主变量和指示变量)
END DECLARE SECTION
例:EXEC SQL BEGIN DECLARE SECTION;
char stdno[6];
char stdname[8];
int stdage;
char stdsex[2];
char stddept[20];
EXEC SQL END DECLARE SECTION;
--定义之后的主变量可以在SQL语句中任何一个能够使用表达式的地方出现;主变量名和指示变量前要加冒号(:)作为标志
--例:
EXEC SQL
INSERT INTO S(sno,sname,sage,ssex,sdept)
VALUES(:stdno,:stdname,:stdage,:stdsex,:stddept);
游标是系统为用户开设的一个数据缓冲区,内存中一段连续的存储单元,存放SQL语句的执行结果。
每个游标区都有一个名字,也可以理解为该数据区的指针。
用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。
--建立连接的嵌入式SQL语言:
EXEC SQL CONNECT TO target [AS connection-name] [USER user-name];
--关闭数据库连接的嵌入式SQL语句是:
EXEC SQL DISCONNECT [connection];--常见服务器的标识串,如:@:
--程序运行过程中可以修改当前连接,对应的嵌入式SQL语句为:
EXEC SQL SET CONNECTION connection-name|DEFAULT;
第一步:定义必要的主变量和数据通信区;
第二步:打开数据库;
第三步:用SQL访问数据库,并对返回结果进行处理;
第四步:关闭数据库
(1)说明性语句
专为在嵌入式SQL中说明主变量、SQLCA等而设置的
1.说明主变量
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL END DECLARE SECTION;
这两条语句必须配对出现,相当于一个括号,两条语句中间是主变量的说明
2.说明SQLCA
EXEC SQL INCLUDE SQLCA
(2)数据定义语句
[例] 建立一个“学生”表Student
EXEC SQL CREATE TABLE Student
(Sno CHAR(5) NOT NULL UNIQUE,
Sname CHAR(20),
Ssex CHAR(1),
Sage INT,
Sdept CHAR(15));
(3)数据控制语句
[例] 把查询Student表权限授给用户U1
EXEC SQL GRANT SELECT ON
TABLE Student TO U1;
(4)查询结果为单记录的SELECT语句
这类语句不需要使用游标,只需要用INTO子句指定存放查询结果的主变量
--[例] 根据学生号码查询学生信息。假设已经把要查询的学生的学号赋给了主变量givensno。
EXEC SQL SELECT Sno,Sname,Ssex,Sage,Sdept
INTO :Hsno,:Hname,:Hsex,:Hage,:Hdept
FROM Student
WHERE Sno=:givensno;
--[例] 查询某个学生选修某门课程的成绩。假设已经把将要查询的学生的学号赋给了主变量givensno,将课程号赋给了主变量givencno。
EXEC SQL SELECT Sno,Cno,Grade
INTO :Hsno,:Hcno,:Hgrade:Gradeid
FROM SC
WHERE Sno=:givensno AND Cno=:givencno;
--如果Gradeid < 0,不论Hgrade为何值,均认为该学生成绩为空值。
--a) INTO子句、WHERE子句和HAVING子句的表达式中均可以使用主变量。
--b)查询结果为空做的处理、查询返问的记录中某些列为空NULL。为了表示空值, INTO子句后面的主变量跟有指示变量。
--c)如果査询结果实际上并不是单条记录,而是多条记录,则程序出错,关系数据管理系统会在SQL通信区中返回错误信息。
(5)非CURRENT形式的增删改语句
--[例] 某个学生退学了,现要将有关他的所有选课记录删除掉。假设该学生的姓名已赋给主变量stdname。
EXEC SQL DELETE
FROM SC
WHERE Sno=(SELECT Sno
FROM Student
WHERE Sname=:stdname);
--[例]某个学生新选修了某门课程,将有关记录插入SC表中。假设插入的学号已赋给主变量stdno,课程号已赋给主变量couno。
gradeid=-1; /*用作指示变量,赋为负值*/
EXEC SQL INSERT
INTO SC(Sno,Cno,Grade)
VALUES(:stdno,:couno,:gr :gradeid);
-- 由于该学生刚选修课程,成绩应为空,所以要把指示变量赋为负值
--[例] 将某个系全体学生年龄修改为20,系名已赋给主变量deptname。
EXEC SQL UPDATE S
SET Sage=20
WHERE Sdept=:deptname;
必须使用游标的SQL语句的种类
(1)查询结果为多条记录的SELECT语句
1.说明游标
EXEC SQL DECLARE <游标名> CURSOR
FOR <SELECT语句>;
--定义游标仅仅是一条说明性语句,这时DBMS并不执行SELECT指定的查询操作,而是向系统申请一个数据空间,用于存放未来执行SELECT的结果数据集。
2.打开游标
EXEC SQL OPEN <游标名>;
--打开游标,实际上是执行相应的SELECT语句,把所有满足查询条件的记录从指定表取到缓冲区中;
--这时游标处于活动状态,游标指针指向查询结果集中第一条记录。
3.推进游标
EXEC SQL FETCH [[NEXT|PRIOR|FIRST|LAST] FROM] <游标名>
INTO <主变量>[<指示变量>][,<主变量>[<指示变量>]]...;
--按指定方向推动游标指针,然后将缓冲区中的当前记录取出来送至主变量供主语言进一步处理。
--NEXT|PRIOR|FIRST|LAST:指定推动游标指针的方式
--缺省为NEXT
4.关闭游标
EXEC SQL CLOSE <游标名>;
--关闭游标,释放结果集占用的缓冲区及其他资源
--游标被关闭后,就不再和原来的查询结果集相联系
--被关闭的游标可以再次被打开,与新的查询结果相联系
5.释放游标
DEALLOCATE 游标名
(2)CURRENT形式的UPDATE和DELETE语句
非CURRENT形式的UPDATE和DELETE语句通常:
如果对满足条件的记录分别做不同的修改或删除,则UPDATE和DELETE语句中要用子句:
WHERE CURRENT OF <游标名>
--实际语法:
UPDATE 表名 SET 列名=表达式 WHERE CURRENT OF <游标名>
DELETE FROM 表名 WHERE CURRENT OF <游标名>
--表示修改或删除的是最近一次取出的记录,即游标指针当前指向的记录。
不能使用CURRENT形式的UPDATE语句和DELETE语句:
当游标定义中的SELECT语句带有UNION或ORDER BY子句,该SELECT语句相当于定义了一个不可更新的视图
定义一个查询所有银行的游标,并使用FETCH NEXT逐个提取每行数据,并按下列形式输出:“银行代码:B1100 银行名称:工商银行北京分行 电话010-4573”。
DECLARE @bno char(5),@Bname nvarchar(10),@btel char(8)
DECLARE bank_cursor1 cursor for
select bno, Bname, tel from bankt
open bank_cursor1
fetch from bank_cursor1 into @bno,@bname,@btel
while (@@FETCH_STATUS =0) -- 0 fetch语句成功; -1 fetch语句失败或此行不在结果集中;-2 被提取的行不存在
begin
print '银行代码:'+@bno+' 银行名称:' +@bname +' 电话:'+@btel
fetch from bank_cursor1 into @bno,@bname,@btel
end
close bank_cursor1--关闭游标
deallocate bank_cursor1 --撤销游标(释放资源 )
变量分类:
全局变量:@@变量名:系统用于记录信息
局部变量:@变量名:用户使用
声明局部变量:
DECLARE @变量名 数据类型 [, …n]
赋值:
SET @变量名=值| 表达式 或
SELECT @变量名=值 | 表达式
显示变量的值
PRINT @变量名 或 SELECT @变量名
三类:顺序、分支和循环
BEGIN…END语句
语法格式:
BEGIN
T-SQL 语句序列
END
作用:将T-SQL 语句序列组合成一个语句块,将它们视为一个整体来处理。
IF 布尔表达式
语句块1
[ELSE
语句块2]
WHILE 布尔表达式
循环体语句块
功能:当条件为真,重复执行语句块
--T-SQL创建存储过程
CREATE PROC [EDURE] 存储过程名
[{@参数名 数据类型} [=default] [OUTPUT]]
AS
SQL语句
--执行存储过程
[EXEC [UTE]] 存储过程名 [实参[, OUTPUT][,…n]]
(1)创建不带参数的存储过程
查询计算机系学生的考试成绩,列出学生的姓名、课程名和成绩。
CREATE PROCEDURE student_grade1
AS
SELECT Sname,Cname,Grade
FROM student,sc,course
WHERE student.sno=sc.sno and course.cno=sc.cno
and Sdept=‘CS‘
EXEC student_grade1
(2)创建带输入参数的存储过程
查询某个指定系学生的考试情况,列出学生的姓名、所在系、课程名和考试成绩。
CREATE PROCEDURE student_grade2
@dept char(20)
AS
begin
SELECT Sname,Sdept,Cname,Grade
FROM student s,sc,course c
WHERE s.sno=sc.sno and c.cno=sc.cno
and Sdept= @dept
End
EXEC student_grade2 ‘CS’
(3)创建带多个输入参数的存储过程
查询某个学生某门课程的考试成绩,列出学生的姓名、课程名和成绩。
CREATE PROCEDURE student_grade2
@s_name char(10), @c_name char(20)
AS
begin
SELECT Sname, Cname, Grade
FROM student,sc,course
WHERE student.sno = sc.sno and course.cno = sc.cno
and sname = @s_name and cname = @c_name
end
--按参数位置传递值
EXEC student_grade2 '刘晨', 'VB'
--按参数名传递值
EXEC Student_grade2 @s_name = '刘晨', @c_name='VB'
(4)创建带多个输入参数并有默认值的存储过程
查询某个学生某门课程的考试成绩,若没有指定课程,则默认课程为“数据库基础”
CREATE PROCEDURE student_grade2
@s_name char(10),@c_name char(20)='数据库基础'
AS
SELECT Sname, Cname, Grade
FROM student,sc,course
WHERE student.sno = sc.sno and course.cno = sc.cno
and sname = @s_name and cname = @c_name
--调用参数有默认值的存储过程
EXEC student_grade3 '刘晨'
--等价于执行:
--EXEC student_grade3 ‘刘晨','数据库基础'
(5)创建带多个输入参数并均指定默认值的存储过程
查询指定系、指定性别的学生中年龄大于等于指定年龄的学生的情况。系的默认值为“计算机系”,性别的默认值为“男生”, 年龄的默认值为20
CREATE PROC P_Student
@dept char(20) = '计算机系', @sex char(2) = '男', @age int = 20
AS
begin
SELECT * FROM Student
WHERE Sdept=@dept AND Ssex=@sex AND Sage>=@age
end
--执行1:不提供任何参数值。
EXEC P_Student
--执行2:提供全部参数值。
--EXEC P_Student '信息系', '女', 19
--执行3:只提供第二个参数的值。
EXEC P_Student @sex = '女'
--执行4:只提供第一个和第三个参数的值。
EXEC P_Student @sex = '女' , @age = 19
(6)创建带有输出参数的存储过程
统计指定课程的平均成绩,并将统计的结果用输出参数返回
CREATE PROCEDURE AvgGrade
@cn char(20), @avg_grade int output
AS
SELECT @avg_grade = AVG(Grade)
FROM SC,Course
WHERE Course.Cno = SC.Cno and Cname = @cn
Declare @res int
EXEC AvgGrade 'vb',@res output
Print @res
(7)创建带输入参数和多个输出参数的存储过程
统计指定课程的平均成绩和选课人数,将统计的结果用输出参数返回。
CREATE PROCEDURE Avg_Count
@cn char(20), @avg_grade int output,
@total int output
AS
SELECT @avg_grade = AVG(Grade), @total = COUNT(*)
FROM SC ,Course
WHERE Course.Cno = SC.Cno and Cname = @cn
(8)创建删除数据的存储过程
删除考试成绩不及格学生的修课记录。
CREATE PROCEDURE p_DeleteSC
AS
DELETE FROM sc WHERE grade < 60
(9)创建修改数据的存储过程
将指定课程的学分增加2分。
CREATE PROCEDURE p_UpdateCredit
@cn varchar(20)
AS
UPDATE course SET credit=credit+2
WHERE cname = @cn
(10)删除存储过程
DROP PROC [ EDURE ] 存储过程名
数据库的完整性是指数据的正确性和相容性
数据的完整性和安全性是两个不同概念
区别是:
完整性:防止数据库中存在不正确的数据
安全性:防止恶意破坏和非法存取
关系模型的实体完整性:主键不能为空
CREATE TABLE中用PRIMARY KEY定义
单属性构成的码有两种说明方法
对多个属性构成的码只有一种说明方法
例如:将Student表中的Sno属性定义为码
(1)在列级定义主码
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
Ssex CHAR(2) ,
Sage SMALLINT,
Sdept CHAR(20));
(2)在表级定义主码
CREATE TABLE Student
(Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2) ,
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno)
);
将SC表中的Sno,Cno属性组定义为码
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno) /*只能在表级定义主码*/
);
插入或对主码列进行更新操作时,RDBMS将按照实体完整性规则自动进行检查:
检查主码值是否唯一,如果不唯一则拒绝插入或修改
检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改
关系模型的参照完整性定义:
在CREATE TABLE中用FOREIGN KEY短语定义那些列为外码
用REFERENCES短语指明这些外码参照哪些表的主码
例如:关系SC中一个元组表示一个学生选修的某门课程的成绩,(Sno,Cno)是主码。Sno,Cno分别参照引用Student表的主码和Course表的主码
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno, Cno), /*在表级定义实体完整性*/
FOREIGN KEY (Sno) REFERENCES Student(Sno),
/*在表级定义参照完整性*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)
/*在表级定义参照完整性*/
);
参照完整性检查和违约处理
1. 拒绝(NO ACTION)执行
默认策略
2.级联(CASCADE)操作
3.设置为空值(SET-NULL)
对于参照完整性,除了应该定义外码,还应定义外码列是否允许为空
实例:显式说明参照完整性的违约处理
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY(Sno,Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno)
ON DELETE CASCADE /*级联删除SC表中相应的元组*/
ON UPDATE CASCADE, /*级联更新SC表中相应的元组*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)
ON DELETE NO ACTION
/*当删除course 表中的元组造成了与SC表不一致时拒绝删除*/
ON UPDATE CASCADE
/*当更新course表中的cno时,级联更新SC表中相应的元组*/
);
用户定义的完整性就是针对某一具体应用的数据必须满足的语义要求
RDBMS提供,而不必由应用程序承担
定义方法
CREATE TABLE时定义
例如:
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT NOT NULL,
PRIMARY KEY (Sno, Cno),
/* 如果在表级定义实体完整性,隐含了Sno,Cno不允许取空值,则在列级不允许取空值的定义就不必写了 */
);
CREATE TABLE DEPT
(Deptno NUMERIC(2),
Dname CHAR(9) UNIQUE,/*要求Dname列值唯一*/
Location CHAR(10),
PRIMARY KEY (Deptno)
);
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY,
Sname CHAR(8) NOT NULL,
Ssex CHAR(2) CHECK (Ssex IN (‘男’,‘女’) ) ,
/*性别属性Ssex只允许取'男'或'女' */
Sage SMALLINT,
Sdept CHAR(20)
);
违约处理
插入元组或修改属性的值时,RDBMS检查属性上的约束条件是否被满足
如果不满足则操作被拒绝执行(默认)
定义方法
在CREATE TABLE时可以用CHECK短语定义元组上的约束条件,即元组级的限制
同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件
例如: 当学生的性别是男时,其名字不能以Ms.打头。
CREATE TABLE Student
(Sno CHAR(9),
Sname CHAR(8) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno),
CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%')
/*定义了元组中Sname和 Ssex两个属性值之间的约束条件*/
);
--性别是女性的元组都能通过该项检查,因为Ssex=‘女’成立;
--当性别是男性时,要通过检查则名字一定不能以Ms.打头
违约处理
插入元组或修改属性的值时,RDBMS检查元组上的约束条件是否被满足
如果不满足则操作被拒绝执行
完整性约束命名子句
CONSTRAINT <完整性约束条件名>
[PRIMARY KEY短语
|FOREIGN KEY短语
|CHECK短语]
-- 建立学生登记表Student,要求学号在90000~99999之间,姓名不能取空值,年龄小于30,性别只能是“男”或“女”。
CREATE TABLE Student
(Sno NUMERIC(6)
CONSTRAINT C1 CHECK (Sno BETWEEN 90000 AND 99999),
Sname CHAR(20)
CONSTRAINT C2 NOT NULL,
Sage NUMERIC(3)
CONSTRAINT C3 CHECK (Sage < 30),
Ssex CHAR(2)
CONSTRAINT C4 CHECK (Ssex IN ( '男','女')),
CONSTRAINT StudentKey PRIMARY KEY(Sno)
);
--在Student表上建立了5个约束条件,包括主码约束(命名为StudentKey)以及C1、C2、C3、C4四个列级约束。
修改表中的完整性限制
使用ALTER TABLE语句修改表中的完整性限制
/*修改表Student中的约束条件,要求学号加新的约束条件改为在900000~999999之间,年龄由小于30改为小于40.*/
/*可以先删除原来的约束条件,再增加 */
DROP CONSTRAINT C1;
ALTER TABLE Student
ADD CONSTRAINT C1 CHECK (Sno BETWEEN 900000 AND 999999),
ALTER TABLE Student
DROP CONSTRAINT C3;
ALTER TABLE Student
ADD CONSTRAINT C3 CHECK (Sage < 40);
触发器是一种特殊类型的存储过程,它不同于存储过程。
当对某一表进行诸如UPDATE、INSERT、DELETE 这些操作时,SQL Server 会自动执行触发器所定义的SQL 语句,从而确保对数据的处理必须符合由这些SQL 语句所定义的规则。
功能
强化约束:触发器能够实现比CHECK 语句更为复杂的约束。
跟踪变化:触发器可以侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化。
级联运行:触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。例如,某个表上的触发器中包含有对另外一个表的数据操作(如删除,更新,插入)而该操作又导致该表上触发器被触发
种类
最常用的是DML触发器
DML触发器的分类
AFTER 触发器:FOR触发器与AFTER触发器是一个作用,只有执行某一操作(INSERT、UPDATE、DELETE)之后,触发器才被触发,且只能在表上定义
INSTEAD OF 触发器:在数据更新到数据库之前执行的操作。并不执行其所定义的操作(INSERT、 UPDATE、 DELETE),而仅是执行触发器本身。
插入表和删除表(魔术表)
插入表(inserted)和删除表(deleted)被称为魔术表,主要保存因用户操作而被影响到的原数据值或新数据值。
这两个表的结构总是与被该触发器作用的表有相同的表结构。
这两个表是动态驻留在内存中的,当触发器工作完成,这两个表也被删除。
这两个表是只读的,即用户不能向这两个表写入内容,但可以引用表中的数据。
创建触发器
用CREATE TRIGGER命令创建触发器的语法如下:
CREATE TRIGGER trigger_name
ON { table | view }
[ WITH ENCRYPTION ] --加密触发器定义的sql文本
{
{ { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] }
[ NOT FOR REPLICATION ]
AS
[ { IF UPDATE ( column )
[ { AND | OR } UPDATE ( column ) ] [ ...n ]
| IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
{ comparison_operator } column_bitmask [ ...n ]
} ]
sql_statement [ ...n ]
}
}
实例:
新建一个贷款记录统计表 LoanNum,存放每一个法人单位的贷款次数。为 LoanT 表创建一个 INSERT 语句级触发器,当有新的贷款记录插入时,需要及时更新 LoanNum 表中该法人的贷款次数。
CREATE TRIGGER tr61
ON loant
for insert
AS
BEGIN
declare @eno char(7),@cnt int
update LoanNum
set cnt=a.cnt+b.cnt
from LoanNum a,(select eno,count(*) as cnt
from inserted
group by eno) b
where a.Eno=b.Eno
END
创建一个 AFTER 行级触发器,当对 LoanT 表的贷款金额(Lamount)进行修改时,若金额减少了 10%, 则将此次操作记录到另外一张表 L_U(Eno,Bno,Oldamount,Newamount),其中 Oldamount 是修改前的金 额,Newamount 是修改后的金额。
create table L_U
(Eno char(7),
Bno char(12),
Oldamount int,
Newamount int)
Go
CREATE TRIGGER tr62
ON LoanT
after update
AS
BEGIN
declare @eno char(7),@bno char(12)
declare @oldnum int,@newnum int
declare newold cursor for
select d.eno,d.bno ,d.lamount,i.lamount
from deleted d, inserted i
where d.Eno =i.Eno and d.bno=i.bno and d.Ldate=i.Ldate
open newold
fetch from newold into @eno,@bno,@oldnum,@newnum
while @@FETCH_STATUS =0
begin
if @newnum=cast(@oldnum *(1-0.1) as int)
begin
insert into L_U
values(@eno,@bno,@oldnum,@newnum)
end
fetch from newold into @eno,@bno,@oldnum,@newnum
end
close newold
deallocate newold
END
激活触发器
触发器的执行,是由触发事件激活的,并由数据库服务器自动执行
多个触发器的执行顺序为:
(1) 执行该表上的BEFORE触发器;
(2) 激活触发器的SQL语句;
(3) 执行该表上的AFTER触发器。
删除触发器
删除触发器的SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。
数据冗余:某个字段重复出现,导致浪费储存空间,而且导致更新数据代价很大,否则面临数据不一致危险;导致异常插入和删除.
**数据依赖:**一个关系内部属性与属性之间的一种约束关系。
**函数依赖:**某个属性集决定另一个属性集时,称另一属性集依赖于该属性集。
平凡函数依赖
当关系中属性集合Y是属性集合X的子集时(Y⊆X),存在函数依赖X→Y,即一组属性函数决定它的所有子集,这种函数依赖称为平凡函数依赖。
非平凡函数依赖
当关系中属性集合Y不是属性集合X的子集时,存在函数依赖X→Y,则称这种函数依赖为非平凡函数依赖。
完全函数依赖
设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。
例如:通过{学生学号, 选修课程名}可以得到{该生本门选修课程的成绩},而通过单独的{学生学号}或者单独的{选修课程名}都无法得到该成绩,则说明{该生本门选修课程的成绩}完全依赖于{学生学号,选修课程名}
部分函数依赖
设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。
例如: 通过{学生学号,课程号}可以得到{该生姓名},而通过单独的{学生学号}已经能够得到{该生姓名},则说明{该生姓名}部分依赖于{学生学号,课程号};
又比如, 通过{学生学号,课程号}可以得到{课程名称},而通过单独的{课程号}已经能够得到{课程名称},则说明{课程名称}部分依赖于{学生学号,课程号}。(部分依赖会造成数据冗余及各种异常。)
传递函数依赖
设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。
例如: 在关系R(学号,宿舍,费用)中,通过{学号}可以得到{宿舍},通过{宿舍}可以得到{费用},而反之都不成立,则存在传递依赖{学号}->{费用}。(传递依赖也会造成数据冗余及各种异常。)
范式:范式是符合某一种级别的关系模式的集合。关系数据库中的关系必须满足一定的要求,满足不同程度要求的为不同范式。
规范化:一个低一级的范式的关系模式可通过模式分解转换成高一级的关系模式的集合,这个过程叫规范化
候选码:若K为关系模式R<U>中的属性组合,若U完全函数依赖于K则称K为R的候选码,简称为码。
超码:若U函数依赖于K则称K为超码,候选码是一种特殊的超码,候选码的超集(若存在)一定是超码,候选码的任何真子集不一定是超码
**主属性:**包含在任何一个候选码中的属性称为主属性 不包含在任何候选码中的属性称为非主属性
**外码:**关系模式R中的属性或属性组X不为R的码,但X是另外一个关系模式的码,则称X为外码。
范式之间的关系:5NF ⊂ 4NF ⊂ BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF
**第一范式:**满足第一范式的关系模式必须满足每一个分量都是不可分的数据项
第二范式:若R属于1NF 且每一个非主属性完全函数依赖于任何一个候选码,则R属于2NF.即符合1NF 消除部分依赖
**第三范式:**设关系模式R属于第一范式,若 不存在这样的码X,属性组Y,以及非主属性Z (Z⊈Y) 使得Y依赖于X,Z依赖于Y成立,且X不依赖于Y,则称R为3NF。
第三范式性质:若关系模式R属于第三范式,则每一个非主属性既不传递依赖与码,也不部分依赖于码,因此,若R属于第三范式,则必有R属于第二范式。即符合2NF,并且,消除传递依赖
BCNF (BC范式):若关系模式R属于第一范式,若属性组Y依赖与码X,且Y不是X的子集时X必含有码,则R属于BC范式。通俗的讲,就是关系模式R中决定因素一定是码(每一个决定因素都包含码),则R属于BC范式 即符合3NF,并且,主属性不依赖于主属性
若一个关系达到了第三范式,并且它只有一个候选码,或者它的每个候选码都是单属性,则该关系自然达到BC范式。
满足BCNF的关系模式具备的性质:
概念:一个数据库操作序列、一个不可分割的工作单位
恢复和并发控制的基本单位,也是数据库管理系统的基本工作单位
一个事务可以是一条或多条SQL语句,也可以包含一个或多个程序。一个程序常包含多个事务
--显式定义事务:
BEGIN TRANSACTION
…
COMMIT
…
ROLLBACK
事务的特性(ACID特性)
**原子性(Atomicity):**事务包含的操作,要么都做,要么都不做。
一致性(Consistency):事务的执行,必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性(Isolation):一个事务的执行不能被其他事务干扰,即一个事务的内部操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
持续性(Durability ):也叫永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
保持事务的ACID特性需要的条件:并发控制、恢复机制。
事务内部的故障: 定义事务时事物内部可以通过事务程序本身发现的故障,或不能被事务程序本身发现的非预期故障。狭义上的事务故障,仅指非预期的故障,恢复方法为:撤销事务(UNDO)
系统故障: 称为软故障,是指造成系统停止运转的任何事件,使得系统要重新启动。发生系统故障时,事务未提交,则可以==强行撤消(UNDO)所有未完成事务来恢复数据;如果事务已提交,但缓冲区中的信息尚未完全写回到磁盘上,则应重做(REDO)==所有已提交的事务。
**介质故障:**称为硬故障,指外存故障。磁盘损坏、磁头碰撞、操作系统的某种潜在错误、瞬时强磁场干扰引起的外部储存故障。恢复方式为:装入数据库发生介质故障前某个时刻的数据副本;重做自此时始的所有成功事务,将这些事务已提交的结果重新记入数据库。
计算机病毒:一种人为的故障或破坏,是一些恶作剧者研制的一种计算机程序;可以繁殖和传播;能破坏、盗窃系统中的数据或者破坏系统文件。
**恢复操作的基本原理: **冗余;即利用存储在系统其它地方的冗余数据来重建数据库中已被破坏或不正确的那部分数据
转储:是指DBA将整个数据库复制到磁带或另一个磁盘上保存起来的过程,备用的数据称为后备副本或后援副本
转储方法:
转储方式:
日志文件(log)是用来记录事务对数据库的更新操作的文件
以记录为单位的日志文件内容:
日志文件的作用
进行事务故障恢复
进行系统故障恢复
协助后备副本进行介质故障恢复
登记日志文件
为保证数据库时可恢复的,登记日志文件必须遵行以下两条原则:
事务故障: 系统利用日志文件==撤销(UNDO)==事务对数据库进行的修改
系统故障:
**介质故障:**重装数据库,然后重做已完成的事务
在日志文件中增加检查点记录(checkpoint)
增加重新开始文件
恢复子系统在登录日志文件期间动态地维护日志 ,方法是周期性地执行检查点、保存数据库状态的操作
使用检查点方法可以 改善恢复效率
并发操作:在多用户共享的系统中,多用户同时对同一数据的存取情形称为并发操作.
并发引起的数据不一致性:
封锁:指事务T在对某个数据对象操作之前,对其加锁。在T未释放锁之前,其他的事务不能更新此数据对象。
锁的分类:
**封锁协议:**共享锁(S锁或读锁):保证其他事务可以读A,但在T释放A上的S锁之前,不能对A做任何修改。
三级封锁协议:
**活锁:**使某个事务永远处于等待状态,而得不到执行的现象称为活锁。
**避免活锁的方法:**先来先服务。
死锁:两个或两个以上的事务在执行过程中,由于竞争资源(数据库数据)或者由于彼此通信而造成的一种阻塞,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁
死锁的预防:
死锁的诊断:
**两段锁协议:**指所有事务必须分两个阶段对数据项加锁和解锁。
若并发执行的所有事务均遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的。
封锁粒度:封锁对象的大小。
**封锁对象:**属性、元组、关系、数据库
多粒度封锁方式:显式封锁和隐式封锁。
显式封锁是应事务的要求直接加到数据对象上的封锁;
即从头扫描日志文件)
2. 对撤销(Undo)队列事务进行撤销(UNDO)处理
3. 对重做(Redo)队列事务进行重做(REDO)处理
**介质故障:**重装数据库,然后重做已完成的事务
在日志文件中增加检查点记录(checkpoint)
增加重新开始文件
恢复子系统在登录日志文件期间动态地维护日志 ,方法是周期性地执行检查点、保存数据库状态的操作
使用检查点方法可以 改善恢复效率
并发操作:在多用户共享的系统中,多用户同时对同一数据的存取情形称为并发操作.
并发引起的数据不一致性:
丢失修改: T1、T2读入同一数据并修改,
T2提交的结果破坏了T1提交
的结果。
[外链图片转存中…(img-Td0vzfJi-1609747770902)]
不可重复读: T1读数据后,T2执行更新操作,使T1第二次读取的不是前一次读取结果。
[外链图片转存中…(img-VINDGeSu-1609747770903)]
脏读:T1修改数据并写回磁盘,T2读取同一数据后,T1被撤销即数据恢复原值,T2读的数据与DB中的不一致,称“脏”数据。
[外链图片转存中…(img-0VV41n9x-1609747770904)]
封锁:指事务T在对某个数据对象操作之前,对其加锁。在T未释放锁之前,其他的事务不能更新此数据对象。
锁的分类:
**封锁协议:**共享锁(S锁或读锁):保证其他事务可以读A,但在T释放A上的S锁之前,不能对A做任何修改。
三级封锁协议:
[外链图片转存中…(img-XEvhpWuD-1609747770904)]
**活锁:**使某个事务永远处于等待状态,而得不到执行的现象称为活锁。
[外链图片转存中…(img-h5jrtmnA-1609747770905)]
**避免活锁的方法:**先来先服务。
死锁:两个或两个以上的事务在执行过程中,由于竞争资源(数据库数据)或者由于彼此通信而造成的一种阻塞,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁
[外链图片转存中…(img-VdJQKEt4-1609747770905)]
死锁的预防:
死锁的诊断:
**两段锁协议:**指所有事务必须分两个阶段对数据项加锁和解锁。
若并发执行的所有事务均遵守两段锁协议,则对这些事务的任何并发调度策略都是可串行化的。
封锁粒度:封锁对象的大小。
**封锁对象:**属性、元组、关系、数据库
多粒度封锁方式:显式封锁和隐式封锁。
显式封锁是应事务的要求直接加到数据对象上的封锁;
隐式封锁是该数据对象没有独立加锁,是由于其上级结点加锁而使该数据对象加上了锁。