数据库复习整理

数据库复习整理

第一章 数据库系统概论

数据库概念与特点

数据库的基本概念

  • 数据:描述事物的符号记录,数据形式具有多样性
    • 结构化数据 如数据库的每条记录
    • 非结构化数据:文本、图数据、图像、音频、视频
  • 数据库:长期储存在计算机内、有组织可共享的数据集合。具有较小冗余度、较高的数据独立性、易扩展性,并可为各种用户共享。
  • 数据库管理系统DBMS:用户和操作系统间的数据管理软件(连接用户和操作系统)|数据组织、存取、管理和维护等功能
    • 数据定义
    • 数据组织、存储、、管理
    • 数据操纵
    • 数据库的事务管理和运行管理
    • 数据库建立和维护
    • 其他功能
  • 数据库系统:有数据库,DBMS及其应用开发工具、应用程序、DBA及相关人员组成的存储、管理、处理和维护数据的系统

**数据管理:**对数据进行分类、组织、存储、检索、维护

数据管理技术发展: 人工管理阶段 → 文件管理阶段 → 数据库管理阶段 人工管理阶段\to 文件管理阶段\to 数据库管理阶段 人工管理阶段文件管理阶段数据库管理阶段

数据库管理阶段:数据结构化(记录内部、记录之间、文件之间有结构)、存取粒度小
			低冗余、高共享、易扩充
			数据独立性高
			DBMS统一管理和控制

与文件系统相比,数据库系统的特点有:✨

数据结构化(整体数据结构化,数据间有联系);数据共享性高、冗余度低、易扩展(保证数据一致性);数据独立性高(物理存储、逻辑存储;独立是指用户端与数据库端间的独立性);数据由数据库管理系统统一管理和控制(数据安全性、数据完整性(正确性、有效性、相容性)检查、并发控制、数据库恢复)

信息世界涉及的基本术语

  • 实体(矩形)
  • 实体集:同类实体的集合
  • 实体型:同类事务所具有的共同特征和性质
  • 属性(椭圆):实体集共同具有的某一特征
  • 域:属性的取值范围
  • 码:唯一标识实体的属性子集
  • 联系(菱形表示)

**数据模型:**✨

是对现实世界数据特征的抽象,是数据库系统的核心和基础。

数据模型被分为两大类:1概念模型、2逻辑模型和物理模型

**概念模型:**被用于数据库设计,按用户观点对数据和信息进行建模

涉及实体-联系方法,ER模型,主要用于数据库设计

**逻辑模型:**层次模型、网状模型、关系模型、面向对象数据模型等,按计算机系统观点对数据建模,主要用于数据库管理系统的实现

格式化模型(实体之间的联系转换成记录之间的两两联系,记录间匹配)树形

层次模型:所谓层次模型就是记录与记录之间的联系只能一对多,父节点对应多个子节点,子节点只有一个父节点

​ 约束:无父节点,不能插入子节点;删除父节点,子节点全部丢失

​ 优缺点:简单清晰,查询效率高(指针),完整性支持;现实中联系多非层次、查询子节点须通过父节点

网状模型:多个父节点,或多个无父节点。如一个记录可能存在与多条父节点记录有联系,如学生成绩(连接通过记录,不涉及规范化等问题)

​ 约束:码;保证一个联系是一对多;支持父节点记录和子节点记录间的约束条件

​ 优缺点:更好描述现实,存取效率高;结构复杂,网状模型DDL,DML复杂,记录之间是通过存储路径实现的

关系模型:✨✨✨(表实现,表间匹配)

​ 建立在严格的数学概念上,关系数据库系统采用这种模型作为组织方式。每个关系的数据结构是一张规范化的二维表,一个关系通常说是一张表。

​ 关系、元组、属性、码、域、分量、关系模式(对关系的描述,关系名(属性1,属性2,…,属性n))

​ 约束:实体完整性、参照完整性、用户定义完整性

​ 其中操作对象和操作结果都是关系,不像格式化模型(前两个)那样是单记录操作方式;对用户隐藏存取路径

​ 优缺点:建立在严格数学概念上,概念单一清晰,数据安全性高;查询效率较差,开发难度大

**物理模型:**数据底层抽象,描述数据在系统内部的表示和存储方式

基本数据模型组成要素:

  • 数据结构:数据库静态特性的描述,描述数据库组成对象及对象之间的联系
  • 数据操作:数据库动态特性的描述,数据操作及操作规则,增删改查
  • 数据的约束条件,完整性规则,数据及其联系的制约(约束条件),依存规则(外键、级联操作等)–实体完整性、参照完整性, 语义约束条件

数据库系统的构成

硬件系统:

  • 大内存:加载OS、DBMS模块、应用程序,分配各种缓冲区
  • 足够大的磁盘或磁盘列阵:存储组织级的大规模数据
  • 处理器速度和IO通道能力:提高数据处理呢能力和数据传送效率

软件系统:

  • 操作系统
  • 数据库管理系统
  • 开发工具
  • 数据应用系统

数据库:

  • 系统数据库
  • 用户数据库
  • 数据库镜像或快照等

人员:

  • 数据库管理员
  • 系统分析员和数据库设计人员
  • 应用程序员
  • 用户

DBA职责:全面管理和控制数据库系统

数据库模式三级结构

image-20221108215631377**image-20221124102247772

外模式(用户视图,算法产生,非物理存储数据,应用程序依赖于外模式):外模式也称子模式或用户模式,它是数据库用户(包括应用程序员和最终用户)能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。

数据库管理系统提供外模式数据定义语言(外模式DDL)来严格定义外模式。

概念模式:也称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图

数据库管理系统提供模式数据定义语言(模式DDL)来严格定义模式

内模式:内模式也称存储模式,一个数据库只有一个内模式。它是数据物理结构和存储方式的描述,是数据在数据库内部的组织方式。

例如,记录存储的方式是堆存储还是按照某个(些)属性值的升(降)序存储,或按照属性值聚簇存储等。

数据库二级映像功能和数据独立性:

外模式/模式映像:每个外模式都有一个这个映像。当模式改变,由数据库管理员改变映像,使外模式保持不变,应用程序根据外模式编写,无需修改逻辑,保证了数据与程序的逻辑独立性。逻辑独立性

模式/内模式映像:全局逻辑结构与存储结构之间的对应关系,存储结构改变,改变映像,保持模式不变,保证数据与程序的物理独立性。

数据库模式,也是全局模式是数据库的关键(逻辑结构)

数据独立性的含义:逻辑独立性,物理独立性,分布独立性(数据库片段的存储场地变化,代码不变)

第二章 关系数据库

关系、关系模式、关系模型blablabla… - 付大石 - 博客园 (cnblogs.com)

关系的形式化定义

关系模型的数据结构非常简单,只包含单一的数据结构——关系,在用户看来逻辑结构是一张二维表

**域 D:**一组具有相同数据类型的值的集合{}

笛卡尔积:

  • n元组:域做笛卡尔积产生n元组,有n个域,元组反映在表里就是一条完整的记录(一行)
  • 分量:元组中每个值称为一个分量
  • 基数M:一个域允许取的不同取值个数称为这个域的基数,笛卡尔积也构成一个域

**关系:**R( D 1 、 D 2 、 D 3 、 D 4 . . . D n D_{1}、D_{2}、D_{3}、D_{4}...D_{n} D1D2D3D4...Dn)

定义:D1 * D2 … * Dn的子集称为D1、D2、 … 、Dn上的关系,表示为上述表达,R表示关系的名字,n是关系的度或目,D1表示某

关系中的每个元素是关系中的元组(Di1, Di2, Di3, … ,Din);若关系中的某一属性组的值能唯一地标识一个元组,而其子集不能,则称该属性组为候选码。

在候选码中选择一个为主码,候选码的属性称为主属性,不包含在任何候选码中的属性称为非主属性或非码属性全码

**关系的三种类型:**基本关系、查询表和视图表

关系的性质:

  • 列同质,同一列中的分量来自同一个域
  • 不同的列可来自同一个域
  • 列无序
  • 不能有相同的元组
  • 行无序
  • 分量必须取原子值

关系模型要求关系必须是规范化的–>范式

关系模式:关系的描述

**R(U,D,Dom,F) 或 R(U):**R关系名,U属性名,D属性组U中属性所来自的域,Dom属性向域的映射集合,F属性间数据的依赖关系

关系模式和关系、关系模型

关系模式:型,是对关系的描述,静态的、稳定的

关系:值,动态的、变化的。指的是关系模式在某一时刻的状态或内容,如学生关系模式在不同的学年,学生关系不同(关系指具体的表)

关系模型:关系模型由关系数据结构,关系操作集合,关系完整性约束三部分组成.

关系完整性

**实体完整性:关系的第一个不变性**✨

主属性不能取空值,否则存在不可表示的实体;码的取值不能重复,否则就存在了两个一样的实体

**参照完整性:关系的第二个不变性**✨

  • F是基本关系R的一个或一组属性,但不是关系R的码;F与基本关系S的主码相对应,被称为R的外码,称R为参照关系,S为被参照关系或目标关系

​ 关系R与S可以是相同的关系

参照完整性的规则:

  • F上的值必须为:空值或者等于S中的某个元组的主码值

用户自定义的完整性

  • 反映具体应用所涉及的数据必须满足的语义要求
  • 关系模型应采用统一的系统的方法处理此类完整性

关系操作

常用的关系操作包括查询操作和插入、删除、修改操作两大部分

查询操作:五种基本操作 选择、投影、并、差、笛卡尔积

关系数据语言的分类:关系代数、关系演算、SQL语言

关系代数(不要跟SQL语句里的指令搞混了)

关系R,S,元组t,A表示某个属性

image-20221112163229843

image-20221112163923422

其中t[A]指的是元组在对应A包含的属性所构成的集合

A ‾ \overline{A} A表示的去掉某一属性A的剩余属性组

选择关系

image-20221112171100612

表示返回满足条件F的关系元组,对于选择条件的F逻辑表达式形式为 X 1 θ Y 1 , θ 表示各种关系运算符,大于、等于、小于等 X_{1}\theta Y_{1},\quad\theta表示各种关系运算符,大于、等于、小于等 X1θY1,θ表示各种关系运算符,大于、等于、小于等。在基本条件运算间可以加一些逻辑运算 ⌝ 非、 ∨ 或、 ∧ 与 \urcorner非、\lor或、\land与 非、或、;;行运算

投影

image-20221112172339248

表示提取属性,产生新的关系。即求属性间的关系

image-20221112172739767 如该例子,指的是求Student关系在上sname、sage两个属性上的投影

连接

image-20221112174201517

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

特殊的等值连接为去掉重复的属性列

我们在做自然连接的时候,选择两个而关系在公共属性上值相等的元组构成新的关系。此时,关系R中某些元组有可能在S中不存在公共属性上值相等的元组,从而造成R中这些元组在操作时被舍弃了,同理,S中也有可能被舍弃,这些被舍弃的元组称为悬浮元组,当把悬浮元组保存在结果关系中时,称为外连接。

image-20221124111658704*注意自然连接的连接条件

image-20221124111945433

除运算

设关系R除以关系S的结果为关系T,则T包含所有在R但不在S中的属性及其值,且T的元组与S的元组的所有组合都在R中。采用象集来定义除法:
image-20221112181749013

我对于象集的理解是:通过元组在某一属性的分量等于某一条件值来确定选定的元组或者记录,然后再提取获得元组在某些属性上的分量

image-20221112181815151

用来查询包含表2某些属性值的表1中的属性,注意其中对于S在属性y上的映射集合被看作了一个主体。条件表示元组包含与关系R的同时,投影是象集的一个子集,注意是在R上的象集包含S上的属性组。注意是S在Y上的投影是 Y x Y_{x} Yx象集的子集

除法运算是这样定义的:给定关系R(X,Y)和S(Y,Z),X,Y,Z为属性组。R ÷ \div ÷S满足元组在X上的分量值x的象集 Y x Y_{x} Yx包含关系S在属性组Y上投影的集合,所以对于筛选的满足X=x的需要包含该投影,而不是交集关系

image-20221124113823484

Z变化,X和Y不变,image-20221124113942749

书本例题P55

查询练习:✨
image-20221124115509947

广义关系运算

不重要

image-20221124114445625 image-20221124114501398 image-20221124114516876

第三到五章 SQL部分(看作业题、例题为主)

第三章 SQL标准语言

SQL语言特点

  • 一体化语言,综合统一:集DDL\DML\DCL于一体,系统运行时,模式修改不受限制;用户数据与系统数据的统一(DDL指创建和完整性约束定义;DML指增删改查;DCL指账户管理、授权管理)
  • 非过程化语言:指出做什么即可,存储路径和操作过程对用户透明
  • 集合操作方式:一次一集合
  • 一种语法,两种方式:联机交互或嵌入高级语言
  • 语言简洁,易学易用

SQL语言与数据库三级模式结构

  • 模式:主要对应基本表的定义和操作(数据库) SQL支持基本表的创建、操纵、删除等
  • 外模式:主要对应视图的定义和操作(面向应用) SQL支持视图的定义、操作、删除等
  • 内模式:主要对应存储文件和数据索引的定义 SQL支持索引的定义、使用、删除/ SQL支持数据存储位置定义等
image-20221113140834888

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

基本表本身是独立存在的表,在关系数据库管理系统中一个关系就对应一个基本表,一个或多个基本表对应一个或多个存储文件,一个表可以带若干索引,索引也存放在存储文件中。

存储文件的逻辑结构组成了关系数据库的内模式。存储文件的物理结构对最终用户是隐蔽的。

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

数据库各个层级结构

模式(schema)或者架构 是数据库体系结构中的一个节点:逻辑地将数据库对象分类地容器

对于SQL Server数据库来说。
访问具体的一个表,可以由4个部分组成
分别为服务器名, 数据库名,模式名,表名。

对于访问本地的数据库
因为服务器已经连接上了,因此不用指定
数据库名,通过  use  数据库名 指定了
模式名,如果不指定的话, 数据库默认使用dbo模式。

对于访问链接服务器。
链接服务器名.数据库名.模式名.表名

模式(schema) 是用于在一个大项目中的各个小项目
每个小项目的表, 放在各自的模式(schema)下面.
这样, 遇到小项目里面. 有相同名字的表的话, 不会发生冲突.
模式就是用于分类的

例如一个公司的系统.
里面分2个子系统, 分别为财务系统和人力资源系统.
这2个系统, 共用一个数据库
.
那么财务系统的表, 可以放在财务的模式(schema).
人力资源系统的表,放在人力资源系统的模式里面。

这2个子系统, 能够互相访问对方的表
但是又不因为 表重名的问题,影响对方。
数据库

学了数据库维护,我们可以发现,一个事务是同时写入数据库物理文件和日志文件中的,事务先加入缓存区,然后再写盘,先写日志文件,再写数据库文件,便于回滚。其中有主要数据文件,次要数据文件,事务日志文件。

image-20221124144432043
create database h1_19377215
on/*创建数据文件的部分*/
(name=H1_dat, /*数据文件名*/
filename='D:\SQL\MSSM_work\H1_data.mdf',/*文件存储的位置和文件名,后缀如下:主要数据文件mdf,次要数据文件ndf,事务日志文件ldf*/
size=5mb,/*分别为初始容量大小,最大容量 unlimited表示没有限制,每次增加的容量大小*/
maxsize=100mb,
filegrowth=5mb
)
log on/*创建日志文件的部分*/
(name=H1_log,
filename='D:\SQL\MSSM_work\H1_data.ldf',
size=5mb,
maxsize=100mb,
filegrowth=5mb
)

/*也可以定义1个主要数据文件,多个次要数据文件件*/
create database stu
on
primary
(name=,
 filename= .mdf,
 ...
),
(name= ,
 filename= .ndf,
 ...
)

use h1_19377215/*使用该数据库,之后的文件在该数据库中进行*/
drop database h1_19377215/*删除数据库*/
架构
create schema caiwu authorization sa
/*在架构下创建数据库对象*/
create table caiwu.student(...)
/*或者直接在模式后面创建一个表*/
/*删除模式*/
drop schema caiwu <cascade|restrict>
删除模式时必须选择两个模式中的一个,前者表示删除模式的同时把该模式中所有的数据库对象全部删除;后者表示如果该模式中如果含有数据库对象,则拒绝该删除语句的执行
**创建基本表**✨✨✨
/*创建基本表*/
create table 表名/数据库名.模式名.表名
(列名1 数据类型 列完整性约束,
 列名2 数据类型 列完整性约束,
 表完整性约束(主键、外键等)
)

  • 数据类型
字符串类型
char(n)
varchar(n)
text 大字符串
--------------
数值类型
int
float
decimal(p,d)定点数 p数字长度,d小数位数
--------------
时间日期类型
date/time/datetime
------------------
identity字段类型(自增)
可将某个费控数值型字段定义为identity属性,无需手动输入
说明起始值和增幅
identity字段将自动赋值并禁止更新
Fee_id int identity(1,2) not null primary key,
  • 完整性约束

**完整性定义:**正确性(有效的、有意义的,保证进入数据库的数据是符合语义约束的合法数据)、相容性(并发使用时,不出现与实际情况不一致的情况,同一个事实的两个数据应当是一致的)

**完整性受破坏的原因:**终端用户的错误或疏忽;应用程序有错误;OS或DBMS故障;并发控制不当;硬件故障

**完整性控制的功能:**定义功能,定义数据库中的数据要满足语义约束(如check);检查功能:检查用户操作是否违背完整性约束(如主键不能重复);违约相应:违背约束时,采取何策略保护数据完整性(如default)

实体完整性:主键定义

列级约束    列名 数据类型 (完整性约束) primary key
sno varchar(10) not null primary key
表级约束放在表创建的结尾
(完整性约束) primary key (sno,cno)
-----------------------------------------------------
检查时机:插入新元组或修改已有元组的主码值
检查内容:是否有空的主码属性,主码值是否唯一
违约处理:拒绝更新

参照完整性:外键定义✨✨✨

create table sc
(sno char(8) not null references Student(sno),/*列级外键约束*/
 cno char(8) not null references Course(cno),
 grade tinyint null,
 primary key(sno,cno)
)

create table sc
(sno char(8) not null,
 cno char(5) not null,
 primary key(sno,cno),
 foreign key (sno) references student(sno),/*表的sno(sc.sno)是外码/外键,表级外键约束*/
 foreign key (cno) references course(cno)
)
--------------------------------------------------------------
student是被参照关系,被参照列是sno/student是被参照关系(表表现了一种关系)
检查时机:参照关系插入新元组;参照关系修改已有元组的外码值;被参照关系删除元组;被参照关系修改已有元组的主属性取值
违约处理:修改参照关系,当影响到外码值时,需要与被参照关系中的主码相对应
		拒绝执行(被参照关系删除元组——若外码元组尚有记录,拒绝删除被参照关系的元组;  被参照对象修改元组主码--有外键元组记录,不允许),no action
		级联操作(被参照关系删除元组--删除元组,级联删除对应外码元组;  被参照对象修改元组主码--修改的同时,修改对应外码) cascade
		置空操作(被参照关系删除元组--删除元组,将对应外码位置置空;  被参照对象修改元组主码--修改的同时,将对应外码置空) set null
		‘’‘’
对应删除的违约处理,我们可以做如下的违约处理定义
针对删除和更新操作分别定义
‘’‘’

create table stu
(sno char(8) not null primary key,
 sname char(20) not null unique,
 stdept char(20) null default('MIS')
 	references department(dept)
 		on update set null
 		on delete set default,
 sgender char(2) not null check(gender='M' or gender='W')
)

update and delete constraints 有以下违约策略:可选违约策略仅是用于被参照关系地删除和修改操作
no action拒绝操作,不声明违约策略的时候,默认是拒绝策略 | cascade 联级操作|set null置空操作| set default 设置为指定默认值

------------------------------------------------------------------
参照完整性的使用
定义顺序:先定义被参照关系主码,再定义参照关系外码;---》删除被参照关系主码一般先接触外键约束----》删除被参照关系同理----》set null 一般要求外码列允许为空格,set default一般要求外码设置缺失值

对于参照关系修改元组,如果违背了参照完整性,则拒绝修改;对于被参照关系的修改有三种选择策略

**用户自定义完整性**✨✨✨

空值约束、唯一性约束、默认值约束、check约束

空值约束
null(允许为空) | not null

唯一性约束
列级  sname char(20) not null unique   表级  [constraint 约束名称(自设)] unique(sname,sno)

默认值约束
default value
check约束
check表达式只涉及单列
sage int null check(sage<30)
gender char(2) check(gender='男' or gender='女')
check表级约束,涉及多列
check((gender='M' and name like '%先生') or 
      (gender='W' and name like '%女士')
     )
**修改和删除表**✨✨
alter语句的用法
删除列名
alter table 表名 drop column 列名 约束策略(cascade|restrict)--级联操作,拒绝操作
增加列
alter table 表名 add column 列名 属性 约束
修改列的类型信息
alter table 表名 change column 列名 新列名 新属性
重命名表
alter table 表名 rename to 新表名
删除表中主键
alter table 表名 drop primary key
添加主键/*在约束之前都可以添加约束名constraint 约束名,这个名称是自己设的,便于之后对约束进行操作*/
alter table 表名 add constraint 约束名 primary key(主码列)
利用约束名删除约束
alter table 表名 drop constranit 要删除的约束名 约束策略(cascade|restrict)
修改列的属性
alter table 表名 modify column 要修改的列名 新属性
drop table sc--删除表

索引:

  1. 数据结构:顺序文件按索引,B+树索引等
  2. 常用索引类型:唯一索引多值索引;聚簇索引非聚簇索引
  3. 索引使用:
    • 聚簇索引:建在经常进行查询、连接,但极少更新地属性上
    • 唯一索引:创建时检查已有数据是否满足唯一性约束
DML数据操纵语言

sql语句的执行顺序

SQL Select 语句完整的执行顺序:
1、from 子句组装来自不同数据源的数据;
2、where 子句基于指定的条件对记录行进行筛选;
3、group by 子句将数据划分为多个分组; group by多个字段,如group by a,b,c 可以看作将 a,b,c作为联合主键去进行分组匹配
4、使用聚集函数进行计算;
5、使用 having 子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用 order by 对结果集进行排序。asc升序,desc降序

单表查询✨✨✨
select 列名 from 表名 where 记录筛选条件 group by 分组依据/需要打印的不带聚合函数的列名 having 分组条件

为查询结果的各类赋予别名
select count(sc_19377215.sno) as '选课人数',course_19377215.cname,AVG(sc_19377215.grade) as '平均成绩',course_19377215.cno as '选课编号'
from sc_19377215 full join course_19377215 on sc_19377215.cno=course_19377215.cno 
group by sc_19377215.cno,course_19377215.cname,course_19377215.cno
select count(sc_19377215.sno) from sc_19377215 ,course_19377215 where sc_19377215.cno=course_19377215.cno group by sc_19377215.cno
显示的结果为选课人数,这就是as的作用

计算年龄

select sno,DateDiff(yy,sbirthday,getdate()) as '年龄' from student--返回以年份计算的日期差,getdate()返回日期

未查询结果赋予别名

select sno as '学号', 2022-sage as '出生年份' from student

取消重复行

select distinct sno from sc
------------------------------
distinct需要放在所有的列属性前面,表示删除重复的记录(条件是distinct后面的属性构成的记录),注意是整条记录删除

查询满足条件的元组

算数比较符 >, <, =, <>

范围(闭集)between… and

确定集合

select sno,grade from sc where cno in (1,2,3)
select sno,grade from sc where cno not in (1,2,3)

模糊匹配like / not like

对于like后不含有通配符的,可以用=代替

select * from student where sname like '刘军%'--%匹配任意多字符
select * from student where sname like '刘_军'--_匹配单个字符
换行字符'\',使得后面的通配符成为普通字符
空值测试 null表示未知,需要用 is null去匹配,而不要使用=null
复合条件查询
select sno,sname,sage from student where sdept='IS' and sage<19
and 优先级 高于 or 优先级高的后运算

结果排序

select sno, sname from student where sdept=‘IS’ order by sage asc–升序

select sno,sname from student where cno=‘A’ order by grade desc–降序

select top 10 sno,grade from sc where cno like ‘c1%’ order by grade desc–查询成绩排在前10

默认为升序排列,如系号按照升序,同一系中的年龄按照降序排列—》 select * from student order by sdept, sage desc;

集函数

注意select的格式,选择出来的内容需要在group by中或者是一个集函数返回结果

count() 返回的是每个分组的统计结果

count(*):统计符合条件的记录个数,处理的是每个分组的数量
count(sname):统计姓名分量
count(distinct sname):统计有多少不同的姓名分量
----
sum(distinct|all 列名)
avg()
max()
min()

说明:集函数只处理非空值,这对求平均值有意义

​ 集函数不能独立出现在where子句中,子查询除外,因为先where筛选再group by,可以使用having筛选分组结果

select cno,count(*),avg(grade) from sc where sno like '82%' group by cno having avg(grade) <60
查询下表中每个专业要求的必修课数量和学分总和
select dept,count(*),sum(creait)
from course where C_type='必修'
group by dept

连接查询✨✨✨

内连接:两个表中满足连接条件的元组进行连接(满足条件的按照笛卡尔积的方式连接)

写法1

select sc.sno,sname,cno,grade from student,sc where student.sno=sc.sno
image-20221116154208548

写法2

select sc.sno,sname,cno,grade from student inner join sc on student.sno=sc.sno where sdept='MA' and grade<60
inner为默认选项,可以省略.

外连接:一个表中符合where条件的全部元组,每个元组与另一个表中的零个或N个元组进行连接,与内连接相比保留了空值

外连接包括左连接、右连接、全连接(left join , right join , full join)

左连接,以左表为主表,并在右表中找出符合连接条件的元组进行连接,若找不到,则对应字段取null
select student.sno,sname,cno,grade
from student left join sc
on student.sno=sc.sno
on表示的是两表的连接条件,先连接,再筛选
右连接,同左连接
select student.sno,sname,cno,grade
from sc right join student
on student.sno=sc.sno
全连接,返回符合where条件的两个表的全部元组,相当于左右连接的并集
select sno,sname,sdept,dpt_name,dpt_desc
from student full join department
on student.sdept=department.dpt_id
符合条件的按条件笛卡尔积连接,不符合条件的与null连接

交叉连接:两个表中所有元组任意连接,与内外链接相比不考虑属性值相等;与外连接不同的是,外连接只对属性值相同的元组部分进行笛卡尔积

交叉连接又称为笛卡尔积,如A表有n个元组,B表有m个元组,则连接成n*m元组,再通过where语句筛选即可

两种连接方式,前者是隐式的交叉连接,显式的交叉连接
select studenet.sno,sname,cno,sname
from student,course
where sdept='IS'

select sno,sname,cno,cname 
from student cross join course

自连接:同一个表中的元组根据制定条件相互连接

表中的属性是有关系的,但是打印的时候需要使用别名

image-20221116163346878

该例子中,对表和属性都使用了别名,其中as是可以省略的,也可写为(注意先执行from语句,所以后面跟的属性前缀也应该用表别名)

select first.cno as 课号, first.cpno as 先行课, second.cpno as 间接先行课
from course as first,course as second
where first.cpno=second.cno

复合条件连接

这种还是用例子最好

统计IS系平均成绩大于90的学生学号、姓名、平均成绩
select sc.sno,sname,avg(grade)
from student,sc
where student.sno=sc.sno and sdept='IS'
group by sc.sno,sname
having avg(grade)>90

按专业统计各课程的选课人数和平均成绩
select sdept,cno,count(*),avg(grade)
from student,sc
where student.sno=sc.sno
group by sdept,cno

比较查询

对单条记录可以直接用比较运算符
对多条记录,使用 
嵌套查询

无非就是在where或者select后加个选取条件,子查询不用于order by子句,如果内外层无关的嵌套内层先执行子查询条件,再执行外层条件;如果内外层相关,则内外交叉

嵌套查询可用连接查询表示

引出子查询的函数
in/not in

比较运算符

any/all  --any任一值,all所有值

例子:
查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄
select sname,sage
from student
where sage<any(select sage
               from student
               where sdept='CS'
)
and sdept<>'CS';

查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄
select sname,sage
from student
where sage<all(select sage
				from student
               where sdept='CS'
)
and sdept<>'CS';

查询计算机系和信息系全部课程都及格的学生学号,姓名
select sno,sname from student
where sdept in ('IS','CS') and 
sno in (select distinct sno from sc) and
sno not in (select distinct sno from sc where grade<60)--很妙,直接排除有不及格成绩同学的学号即可
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
exist(待仔细查找相关内容)
EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 FalseTrueFalse对应的是每条记录,因此对于存在记录的读取进行筛选

exists是一种关联子查询的方法,即内外层相关。将每一行放入比较,当外层记录满足内层查询结果时,就保留。将主查询的数据,放到子查询中做条件验证,根据验证结果(TRUEFALSE)来决定主查询的数据结果是否得以保留。注意not exists 对于and语句只要有一项不满足就返回True
使用for语句的概念来理解就很好理解了,从外向内。in是从里向外。

内外层相关的简单逻辑子查询

查询选修了A课程的学生姓名

select sname from student where exists
(select * from sc where cno='A' and sno=student.sno)

查询每个同学高于自己平均成绩的课程编号和成绩

select sno,cno,grade from sc x where x.grade>
(select avg(grade) from sc y where y.sno=x.sno)

查询选修全部课程的学生姓名

逻辑是:找到一个学生,不存在一门课是在选修记录里没有的✨✨✨

以宋杰为例,宋杰,A 不存在于选课记录中,not exists返回为真,则外层的not exists返回为假,则宋杰被筛除;武谭返回为假,则外层返回为真

我认为一个比较简易的方法就是,一层exist表示一个for语句,然后对最内层的for语句进行判断,然后一层层往外判断

以宋杰为例:

82101 宋杰 A

​ B

​ C

然后每条与sc比较,第二层的not exists返回 A,C,则第一层not exists返回False,则宋杰不返回。

以武谭为例

82102 武谭 A

​ B

​ C

然后每条与sc比较,第二层返回NULL,则第一层not exists返回True,武谭返回

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbpt8WDN-1678455927231)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221125222401863.png)]

另一个例子:

查询至少选修了 学号为82103学生选修的全部课程的学生

select * from student where not exists
(select * from sc scy where scy.sno='82103' and not exists(
select * from sc scz where scz.sno=scy.cno and scz.sno=student.sno)
)
集合查询(会自动删除重复的行)

union集合的并

查询平均成绩>90 或者获得两次以上的同学
select sno from sc group by sno
having avg(grade)>90
union
select sno from excellent_stu group by sno
having count(*)>=2
使用union自动去掉重复元组,使用union all保留重复元组

intersect集合的交

查询...并且...的同学
select sno from sc group by sno
having avg(grade)>90
intersect
select sno from excellent_stu
group by sno having count(*)>=2

except集合的差

前项的结果减去后项的结果
select sno from sc where cno='a'
except
select sno from sc where cno='b'

通过from子句生成的派生表必须指定一个别名

内置函数生成数据
集函数
------
算术函数
ceiling(n)
floor(n)
round(m,n)
abs(n)
sign(n)
rand()返回01的一个随机数
convert(decimal(10,2),n)将数字转化为小数格式,有效数位为10,小数点后两位
-----------------------------------------------------------------
转换函数
convert(格式,数据)
-----------------
字符串函数

-----------
时间串函数
getdate()
datediff()
datediff(yy,birthday,getdate())//datepart start end

用法:in 内外层无关的查询;exists 内外层相关的查询

数据更新(插入、修改、)DML
插入数据
insert into sc (属性) values (数值)
insert into sc (A,B...) select A,B... from student where ... --或者通过函数计算结果传入
select ... into 新表名 from 子查询 where... --创建关系表,同时插入检索结果
select sno,sname,sdept into s_list from student where sno in (select distinct sno from student where grade<60)

修改数据
update 表名 set 列名1=表达式1
			列名2=表达式2...
where 条件
update sc set grade=grade+10 where cno='A'
--将计算机系学生选修A课程的成绩变成5分制形式
update sc set grade=grade*0.05 where cno='A' and sno in (select sno from student where sdept='CS')

删除数据
delete from 表名 where 条件
delete from sc where cno='B' and sno='001'
--删除信息系统系张强同学的选课信息
delete from sc where sno in (select sno from student where sdept='IS' and sname='张强')
插入数据
insert into course_19377215(cno,cname,ccredit)values
('1901','现代程序设计',2),
('1902','数据库',2),
('1903','计算机网络基础',2),
('1904','计量经济学',3),
('1905','数据结构',2),
('1906','计算机组成原理',2)


将子查询结果插入
insert into stu_gpa(sno,sname,sdept,gpa)
select sc_19377215.sno,sname,sdept,convert(decimal(10,2),
(sum(ccredit*grade/25.0)/sum(ccredit))) from
sc_19377215,student_19377215,course_19377215 where
sc_19377215.sno=student_19377215.sno
and sc_19377215.cno=course_19377215.cno
group by sc_19377215.sno,sname,sdept


创建关系表,同时插入检索结果
select sno,sname,sdept into S_list
from student where sno in
(select distinct sno from student where grade<60)


修改数据
方法一
update student t set sdept='Is',cno='10' where sno='001'
update sc set grade=grade+10 where cno='A'
update student set sage=sage+1

update sc set grade=grade*0.05
where cno='A' and sno in 
(select sno from student where sdept='CS')

方法二
/*如果要在已有数据中的字段中插入数据,貌似只能用update,insert只能一次插入一行*/
update course_19377215 set ctype=case when cno='1901' then '必修'
when cno='1902' then '必修'
when cno='1903' then '必修'
when cno='1904' then '必修'
when cno='1905' then '选修'
when cno='1906' then '选修'
when cno='1907' then '选修'
when cno='2001' then '必修'
when cno='2002' then '必修'
when cno='2003' then '必修'
when cno='2004' then '必修'
when cno='2005' then '选修'
when cno='2006' then '选修'
when cno='2007' then '选修'
else ctype end;
有点像c语言的case语句


删除数据
delete from 表名 where 条件
delete from sc where cno='B' and sno='001'
delete from sc where sno
in (select sname from student where sdept='IS' and sname='张强')

视图创建和使用

视图称为虚表,是从一个或几个基本表(或视图)导出的表

create view 视图名 [列名1,列名2,...] as 子查询 [with check option] --[]里表示可有可无的项,子查询指的就是select开头的部分

description:
列名可省,但有计算列或希望重新命名列时,需要列名列表
系统只存储视图的定义,使用时再根据定义生成数据,也就是说视图不会产生数据占系统空间
with check option指对系统更新时,保证更新数据满足视图定义中的谓词条件
---------------------------------------------------------------------------------------
行列子集视图
create view IS_student
as select sno,sname,sage from student where sdept='IS'
with check option

连接视图
create view IS_S1(sno,sname,grade) as
select student.sno,sname,grade
from student,sc
where sdept='IS' and cno='A' and student.sno=sc.sno

从视图中导出视图
create view IS_S2 as
select sno,sname,grade from IS_S1 where grade>90

分组视图
create view S_G(sno,Gavg) as 
select sno,avg(grade) from sc group by sno

带表达式的视图
create view BT_s(sno,sname,sbirth) as
select sno,sname,2022-sage from student

视图删除
drop view 视图名 [cascade]--cascade表示联级操作,联级删除基于本视图创建的其他视图

视图记录的查询、更新、删除操作类似于数据表
但是视图更新会受限,可以更新的是行列子集视图;理论上可更新,但特征未知;理论上不可更新,如:分组视图
视图查询
执行过程为:有效性检查;根据视图的定义,转换成对基本表的查询你;执行对基本表的查询

视图更新(等同于表的操作)
更新的执行:转换成对基本表的更新
视图更新的规则:
1、更新不能影响一个以上的表,如删除、插入、update记录必须属于同一物理表
2、更新不能涉及虚拟列或计算列(逆推易出错)
3、插入时,未赋值的not null列必须有缺省值
4、某些试图不可更新:使用distinct、集函数创建的视图(如果更新需要去做反推之类的,还不一定可行,从计算机的角度来说,及其不合理);使用group by子句创建的视图
通俗来说,就是视图的更新只能直接影响一个真实存在的物理表上的属性,而且不需要去倒推

视图的作用
简化用户操作,清晰的表达查询;从不同角度看待同一数据;保证数据的独立逻辑性;保护数据安全;用于应用程序
DCL数据控制语言
数据库编程

第四章 安全控制

数据库的安全性时指保护数据库以防止不合法使用所造成的数据泄漏、更改或破坏

数据库有关的安全性,主要包括用户身份鉴别、多层存取控制、审计、视图和数据加密等安全技术

用户 数据库管理系统 操作系统 数据库

用户表示和鉴别 数据库安全保护 操作系统安全保护 数据密码存储

数据库安全的威胁因素
  • 非授权用户的恶意存取和破坏–阻止非法操作(身份鉴别、存取控制、视图授权等)
  • 数据库的重要或敏感数据泄露–存取控制、存储和传输加密、审计等
  • 安全环境的脆弱性–硬件安全、操作系统安全、网络系统安全
数据库安全控制

用户身份鉴别

  • 静态口令鉴别:密码
  • 动态口令:短信验证
  • 生物特征识别
  • 智能卡识别

存取访问控制

  • 自主存取控制DAC–将用户权限登记到数据字典,用户对某一数据对象的操作权力称为权限。根据数据字典,接受或拒绝用户指令。
  • 强制存取控制MAC–对读写操作设置许可证级别

视图机制

  • 存取谓词的权限定义:对谓词指定的局部数据,进行授权–如CS专业的老师只能检索本专业学生信息
  • 视图安全机制:对视图授权,间接实现基于谓词的权限定义

审计

  • 审计日志:用户对数据库所有操作的记录文件
  • 审计追踪
  • 可审计的事件
  • 审计功能

数据加密

  • 明文:原始数据
  • 密文:加密后不可识别的数据
  • 存储加密:透明加密、通过函数加密指定的数据
  • 传输加密:基于SSL的传输加密机制

其他安全策略

  • 推理控制
  • 隐蔽信道
  • 匿名模型与隐私
sql sever 安全机制✨

(23条消息) 六、SQL Server数据库用户管理_摸爬滚打的程序媛的博客-CSDN博客_sqlserver在哪管理用户

登录身份的验证模拟

登录名用于连接到sql sever服务器

  • windows身份验证模式
  • sql sever验证模式

管理登录名

管理数据库用户✨

​ 用户是数据库级的主体,是登录名在数据库中的映射

​ 用户是在数据库中执行操作和活动的行动者

​ 数据库用户不能直接拥有表等数据库对象,而是通过模式拥有这些对象

​ 数据库用户管理:创建用户、查看用户信息、修改用户、删除用户等

​ 每个用来登录sql sever的登录名都是一个用户,一个数据库可以拥有多个用户,只有用户才 有权限访问数据库

创建用户
用户是登录名在数据库中的映射,创建用户需要指定登录名
create user <用户名> from login <登陆名> 
with default_schema=<模式名>

用户针对数据库创建(访问权限)
use h1--数据库
create user Bob
from login [BOB]
with default_schema=HR --指的是带有默认模式HR的数据库用户

查看数据库用户信息
select * from sysusers

修改和删除用户
alter user <用户名> with default_schema=<模式名>
drop user <用户名>

​ 特殊用户 DBO, Guest

DBO:数据库默认用户,数据库创建之后,dbo用户就自动存在了

DBO:拥有在数据库中完成所有操作的权限

默认情况下,sa登录名在各数据库中对应的用户是DBO

Guest用户

启动guest账号:grant connect to guest

禁用guest账号:revoke connect from guest

管理数据库角色✨

为帮助您管理服务器上的权限,SQL Server 提供了若干角色,这些角色是用于对其他主体进行分组的安全主体

有固定数据库角色和固定服务器角色

public角色及时特殊的服务器角色也是特殊的数据库角色

权限管理✨

  • 授予语句权限:执行DDL的权力
  • 授予对象权限:具体数据库对象的访问和执行权限 grant
  • 回收权限 revoke
  • 禁止权限 deny
  • 用户最终权限计算:用户所属角色被授予的权限+直接授予该用户的权限-用户所属角色被禁止的权限-该用户被禁止的权限

第五章 数据库编程

过程化SQL
变量与变量赋值
declare 变量名 数据类型
declare @v_sno char(8),@v_cno char(10)--@是必须的,表示一个过程化的变量名
select @v_sno='101',@v_cno='A'--两种赋值方式
set @v_sno='101' 
用索引结果赋值
declare @v_sno varchar(20),@v_cno char(8),@v_grade int
select @v_sno='s001',@v_cno='c1'
select @v_grade=grade from sc where sno=@v_sno and cno=@v_cno
分支语句
表示代码块的开始与结束
begin
...
end
----------

条件语句
if 条件1
begin
	block
end
else if 条件2
begin
	block
end
else
begin
	block
end
--------
if exists(select 语句)
print 1
else
print 0
-------------

while循环语句
select @cnt=1,@nm=0
while(@cnt<100)
begin
	if(@nm>100)
		break
	if(@cnt=5)
	begin
		select @cnt=@cnt+1
		continue
	end
	select @nm=@nm+@cnt*(@cnt-1)
	select @cnt=@cnt+1
end	
游标cursor

游标作用:允许用户在查询结果集上滚动游标,逐行访问记录,按自己的意愿,需求显示和处理这些记录。即:把集合操作转换成单个记录处理方式

优点

  • 允许程序对查询结果集的每一行执行相同或不同的操作
  • 允许根据游标位置,对表中特定行进行删除和更新
  • 是面向集合的数据库管理系统和面向行的程序设计之间的桥梁

缺点:

数据规模大时,开销较大、速度较慢

游标的使用流程:创建游标,打开游标,滚动游标&读取数据,测试游标状态,[动态游标的更新],关闭游标,释放游标

游标创建
declare 游标名 [insensitive][scroll] cursor
for <select 读取的记录>
[for read only|update [of column-name-list]]
-intensitive:用临时表存储游标数据,基本表修改不反应到结果中,游标不允许修改数据。若省略,则对基本表的更新反映在结果中
-scroll所有提取选项均可用给,若省略,则仅支持next

declare s_cur cursor
for select sname from student,sc
where student.sno=sc.sno and cno='A'

open s_cur

fetch s_cur into @v_sname---fetch 游标名 [into fetch target-list(目标变量列表)]

@@fetch_status--测试游标状态,结果为0,语句成功;-1语句失败或此行不在结果集中;-2被提取的行不存在

动态游标更新(批量操作)
update student set sname=@v_new_sname
where current of s_cur

delete from student where current of s_cur

关闭&释放游标
close s_cur
deallocate s_cur
存储过程✨✨✨✨

存放在数据库服务器

输出选修A课程的每个学生的学生姓名 和成绩概况
create procedure prt_stu_name as
begin
	/*声明变量*/
	declare @v_name char(30),@v_grade int
	/*创建游标*/
	declare s_cur cursor for select sname,grade from student,sc
			where student.sno=sc.sno and cno='A'
	/*打开游标*/
	open s_cur
	/*导入数据到变量中*/
	fetch s_cur into @v_name,@v_grade
	/*判断游标读取数据的状态*/
	while(@@fetch_status=0)
	begin
		if (@v_grade>=80) print @v_name+'成绩优良'
		else if(@v_grade>=60) print @v_name+'成绩合格'
		else print @v_name+'成绩不合格'
		/*读取下一行记录*/
		fetch s_cur into @v_name,@v_grade
	end
	close s_cur
	deallocate s_cur
end

输入编号,输出数据

create procedure prt_stu_NM 
@v_cno char(10),--入参
@s_cnt int output as--这些变量都类似与形参,output是出参形式
begin
	/*声明变量*/
	declare @v_name char(30),@v_grade int
	/*创建游标*/
	declare s_cur cursor for select sname,grade from student,sc
			where student.sno=sc.sno and cno=@v_cno
	/*打开游标*/
	open s_cur
	/*导入数据到变量中*/
	fetch s_cur into @v_name,@v_grade
	/*判断游标读取数据的状态*/
	while(@@fetch_status=0)
	begin
		if (@v_grade>=80) print @v_name+'成绩优良'
		else if(@v_grade>=60) print @v_name+'成绩合格'
		else print @v_name+'成绩不合格'
		/*读取下一行记录*/
		fetch s_cur into @v_name,@v_grade
	end
	close s_cur
	deallocate s_cur
end	

执行存储过程
declare @sc_num int
exec prt_stu_NM 'c1',@sc_num output--需要在使用之前声明出参的变量,便于返回结果
print @sc_num//select @sc_num as '选课数'
go

存储过程删除
drop procedure prt_stu_NM
触发器✨✨✨✨✨

DDL触发器:由create,alter,drop等DDL语句触发

DML触发器:由表或视图的insert,update,delete语句触发

登录出发器:由LOGON事件触发

DML触发器
create trigger 触发器名 on 表名
{for|after|instead of}{insert|delete|update}
as sql语句序列

for|after:DML语句操作执行成功后,才触发触发器动作
instead of:执行触发器动作,而不是触发sql语句

DML触发器的可用信息
1、全局变量:@@rowcount返回最近一次操作影响的行数
2、deleted和inserted:驻留内存的制度临时表,只用于触发器
	deleted:执行deleteupdate语句时,符合条件的行被从当前表中删除,并传输到deleted表中
	inserted:在一个插入或更新事务处理中,新建行被同时添加到当前表和inserted表中
	update相当于删除之后再插入,首先旧行被复制到deleted表中,然后新行被复制到目标表和inserted表中

完整性–级联数据删除✨

删除某一学生的记录,级联删除学生的成绩信息
create trigger Td_student1 on student for delete
as
begin
	if @@roucount=0--说明记录已经删完
		return
	delete from sc where sno in
	(select sno from deleted)
	return
end

完整性–参照完整性检测

exists, not exists可以和in,not in 做对比,exists只判断正误,但是可以返回结果集(将记录逐条比对,当比对成功时则该条语句满足条件,被选择)

以下可以翻译成,如果存在(inserted表中有不存在满足sno=inserted.sno表的关系的结果集),那么返回1,也就是说插入了不存在的学生信息

create trigger Tiu_sc on sc for insert,update as
begin
	if exists(select * from inserted where not exists
             (select * from student where sno=inserted.sno))
    begin
    	raiseror('Attempt to insert invaild sno into sc',16,1)
    	rollback transaction
    	return
    end
   	if exists(select*from inserted where not exists
             (select * from course where cno=inserted.cno))
    begin
    	raiseror('Attempt to insert invalid cno into sc.' ,16,1)
    	rollback transaction
    	return
   	end
end  

完整性–数据取值约束

create trigger trg_teacher_sal on teacher_sal
after update,insert
as
begin
	declare @Avg_sal money
	select @avg_sal=avg(sal) from teacher_sal
	if exists(select * from teacher_sal
             where sal>(@Avg_sal*4))
    begin
    	print 'invalid salary'
    	rollback transaction
   	end
end   	

安全性–禁止更新特定列

create trigger trgUpdateGrade
on sc
for update
as
	if update(grade)--表示如果对指定列grade操作,那么报错
	begin
		print 'grade can not be modified!'
		rollback transaction
	end

update() 测试对制定列的updateinsert操作,来决定是否执行触发器里的某些动作

安全性–禁止在特定时间更新数据💕💕💕

create trigger Tsecure_sc on sc for insert,delete,update
as
begin
	if(DateName(weekday,getdate())='星期六' or
      DateName(weekday,getdate())='星期日' or
      convert(int,DateName(hour,getdate()))
      not between 9 and 17)
    begin
    	raiseror('只允许在工作时间操作',16,1)
    	rollback transaction--回滚事务,将已做操作撤销
    end
end

特殊业务逻辑–级联数据更新

create trigger Td_student2 on student for delete
as
begin
	if @@rowcount=0
		return
	insert into stu_graduate
		select sdept,
			cast(datepart(yy,getdate()) as int),
			count(*)
		from deleted
		group by sdept
end		
image-20221117234459236

回滚的是由于触发器触发或者事务执行失败;否则被提交。事务执行过程:触发器、事务同时成功提交或整体撤销

rollback transcation回滚事务,相当于操作的撤销,因为操作是非法的

for 是执行触发器操作以后再执行u,d,i操作;after是之后做;instead of是替代做

触发器删除

命令删除 drop trigger 触发器名称

删除表时,自动删除触发器

数据库连接&嵌入式SQL

第六章 关系理论

R(U,F) U表示的属性, F表示的是这些属性的函数依赖

好的关系模式应尽量避免数据冗余、更新异常、插入异常、删除异常

函数依赖

函数依赖的定义:关系模式R(U), X和Y是U的子集。对R(U)的任意一个关系r,若r中不可能存在两个元组,他们在X上的取值相同在Y上的取值不同,则称X函数确定Y,或Y函数依赖于X,记作X → \rightarrow Y。否则称X不能函数确定Y,或Y不函数依赖于X,记作X ↛ \nrightarrow Y。也就是说对于任意一个映射关系,X都能唯一确定一个Y,X不可能有两个取值。

非平凡的函数依赖 X → Y X\to Y XY, 且Y不是X的子集

平凡的函数依赖 X → Y X\to Y XY, 但Y是X的子集,对于任何关系模式,平凡函数依赖必然成立

**完全函数依赖:**X → \to Y,且对于X的任意一个真子集X’,X’ ↛ \nrightarrow Y,则称Y完全函数依赖于X,记作X → f \xrightarrow{f} f Y(多个属性构成码)(full)

**不完全函数依赖:**X → \to Y,且存在X的一个真子集X’,X’ → \to Y;则称:Y部分函数依赖于X,记作X → P \xrightarrow{P} P Y(partial)

决定因素:若X → \to Y,X称为这个函数依赖的决定因素

X ← → \leftarrow\rightarrow ←→Y:相互决定,X和Y相互函数依赖

不函数依赖

传递函数依赖:若X → \to Y, Y → \to Z,但Y ↛ \nrightarrow X(否则X,Y等价),则称Z对X传递依赖

**候选码:**设K为R<U,F>(关系模式)中的属性或属性组合,若K → F \xrightarrow{F} F U,则K为R的候选码

超码:如果U部分依赖于K,则称K为超码,候选码是最小的超码。

  • 若候选码有多个,则任选其中一个为主码
  • 包含在任何一个候选码中的属性称为主属性;不包含在其中的称为非主属性或非码属性。最简单的情况,单个属性是码;最极端的情况,整个属性组是码,称为全码。

外码:foreign key

范式(难点)

关系数据库的关系是要满足一定要求的,满足不同程度要求的为不同范式

FD函数依赖

(16条消息) 数据库三大范式对数据冗余、更新异常、插入异常、删除异常等问题的解决情况_u011186240的博客-CSDN博客_数据库插入异常

范式:满足一定条件的关系模式的集合称为范式

规范化:一个属于低级范式的关系模式,通过模式分解可以转化为若干个属于高级范式的关系的集合,这个过程就叫规范化。

1NF:每一个属性必须是不可再分的最小数据项,满足这一条件的关系模式属于第一范式。

例如:专业的关系中,专业负责人这一属性可以分为正副两个子属性,则该关系模式不属于第一范式

2NF:如果关系模式属于第一范式,且每一个非码属性完全函数依赖于码,则关系模式属于第二范式

非2NF可能会产生的问题:p183

  • 插入异常:即缺少一部分码值导致固有属性无法插入
  • 删除异常:删除部分码值,删除部分为主属性,导致整个元组需要删除,删除异常
  • 修改异常:不完全依赖,导致修改属性值时对表数据进行复杂的修改

将非2NF转为2NF

  • 第一类非主属性:完全依赖于码

  • 第二类非主属性:部份依赖于码

推论:没有非主属性的关系模式一定属于2NF;单属性做码的关系模式一定属于2NF;二目关系模式属于2NF;

3NF:设关系模式属于第一范式,若不存在这样的码X,属性组Y,及非码属性Z(Z不是Y的子集),使X → \rightarrow Y(Y ↚ \nleftarrow X),Y → \rightarrow Z成立,则该关系模式属于第三范式。

如果关系模式属于第三范式,则该关系模式属于第二范式(若关系模式R$\in$3NF, 则每一个非主属性既不传递依赖于码,也不部份依赖于码) 也就是说当不满足第三范式时一个表可以拆成至少两个

若存在传递依赖关系,出现的问题类似于2NF

证明:ppt,反证法否定结论

修正的第三范式BCNF:关系模式R$\in 1 N F ,若 X 1NF,若X 1NF,若X\rightarrow Y ,且 Y 不是 X 的子集时, X 必含有码,则 R Y,且Y不是X的子集时,X必含有码,则R Y,且Y不是X的子集时,X必含有码,则R\in$BCNF;即每一个决定因素必含有码(意味着不存咋部分依赖),即存在某一属性函数依赖于属性Y,则属性Y包含码。通过例子发现,希望所有的决定因素都应该是码属性,而不存在某一个属性可以决定非主属性 p185

在3NF基础上消除了码属性对其他候选码的部分和传递依赖(消除了任何属性对码的传递依赖和部分依赖)

首先,没有任何属性对码是部份依赖和传递依赖的,则R属于第三范式;其次,码是唯一的决定因素,则R属于BCNF

那么属于BCNF的关系模式是否是完美的呢?同样也会出先数据冗余、数据增删改等问题。

码的真子集不为码,码为真子集的属性组为超码

总结一下,作为一个BCNF,必须满足以下三个性质:
1.所有非主属性都完全依赖于每个候选码。(没有任何属性完全依赖于非码属性组)
这个性质主要是确保2NF(消除了部分依赖)和3NF(消除了传递依赖)。
2.所有主属性都完全函数依赖于每个不包含它的候选码。(候选码内的属性)否则就出现了部分依赖关系,导致2NF不成立
消除了主属性对每个不包含它的候选码的部分依赖和传递依赖。就是我们上面第二个例子。
3.没有任何属性完全函数依赖于非码的任何一组属性。
就是不是超码的属性,虽然可以作为决定因素,但也意味着不是BCNF了。

4.无非码属性对码传递依赖

注意,码是能够决定关系中的任何属性的

————————————————
版权声明:本文为CSDN博主「Check777」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44261106/article/details/104838947

image-20221127203638986

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nT4X7Z90-1678455927232)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221127203718602.png)]

image-20221127203732823

多值依赖:设R(U)是属性集U上的一个关系模式,X,Y,Z是U的子集,且Z=U-X-Y。关系模式R(U)中多值依赖X → → \rightarrow \rightarrow →→Y成立,当且仅当对R(U)的任一关系r,给定的一对(x,z)值,有一组Y的值,这组值仅仅决定于x值而与z值无关

简单来说,(X,Z)确定,有一组Y与之对应,而修改Z,对应的一组Y不变

p186 可见ppt例子是全码关系(因为任何除了全码的属性组无法决定一组记录),显然满足BCNF,但同时观察发现,存在某些依赖关系,即某一属性可以确定某些值。此时不是一个码确定一个元组了。导致数据冗余太大

image-20221127212211987

判断标准,注意条件 U=X+Y+Z,三元关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfBvp4Ie-1678455927233)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221205112816098.png)]

image-20221205112932129

(16条消息) 数据库中的多值依赖的理解_Alan and fish的博客-CSDN博客_多值依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GkSSvb9i-1678455927233)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221127204524659.png)]

多值依赖具有对称性、传递性、函数依赖可以看作是多值依赖的特殊情况、

规范化

4NF:关系模式R<U,F>$\in 1 N F ,如果对于 R 的每个非平凡多值依赖 X 1NF,如果对于R的每个非平凡多值依赖X 1NF,如果对于R的每个非平凡多值依赖X\rightarrow\rightarrow Y ( Y Y(Y Y(Y\nsubseteq$X),X都含有码,则称R属于4NF。4NF不允许非平凡且非函数依赖的多值依赖,非平凡的多值依赖为函数依赖;

4NF就是限制关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。4NF消除非平凡的多值依赖关系,而实质上就是非平凡的函数依赖关系。以上述例子为例,显然课程不是码,因此不属于函数依赖关系,不满足4NF,数据冗余。

显然满足4NF时,就满足BCNF

数据库设计范式2——BC范式和第四范式 - 深蓝 - 博客园 (cnblogs.com)✨✨✨✨✨✨✨

前几个范式都只讨论了属性,码之间的关系,多值依赖的出现,使得需要考虑值的层面

规范化

规范化的目的:为了解决一些关系模式存在的问题,“插入异常,更新异常,删除异常,数据冗余大”

规范化的基本思想:概念单一化,逐步消除数据依赖中不合适的部分。

各种范式及规范化的过程

关系候选码求解✨✨

  1. 将R属性分为L、R、N和LR类:
    L类:仅出现在函数依赖左部的属性;R类:仅出现在函数依赖右部的属性

    N类:左右两边都不出现的属性;LR类:左右两边都出现的属性

  2. X代表L,N类,Y代表LR类

  3. 求X闭包。。。

数据依赖的公理系统

数据依赖公理系统是模式分解算法的基础理论。

例如已知函数依赖集F,问X->Y是否为F所蕴含,就需要以下公理系统

armstrong公理系统:p190

F 逻辑蕴含 X → \rightarrow Y: 对于满足一组函数依赖F的关系模式R<U,F>,其任何一个关系r,若函数依赖X->Y都成立(即r中 任意两个元组t,s,若t[X]=s[X], 则t[Y]=s[Y])

关系模式R满足以下推理规则:(逻辑蕴含,X,Y包含于F的任意一组关系中)
A1自反律:自己映射自己

A2增广率:X → \to Y belongs to F, and Z belongs to U, then XZ → \to YZ belongs to F

A3传递率:若X → \to Y, Y → \to Z 被F所蕴含,则X → \to Z被F所蕴含

推论

  • 合并规则:若X → \to Y, X → \to Y, then X → \to YZ
  • 伪传递规则:若X → \to Y, WY → \to Z, 则XW → \to Z

如:教工号 → \to 系,(系,年份) → \to 系主任,则(教工号,年份) → \to 系主任

  • 分解规则:若X → \to Y, Z ⊆ \subseteq Y, 则X → \to Z

引理:X->A1A2…Ak成立的充要条件为X->Ai(i=1…k)成立

跟代数上的闭包一个道理,所有元素的四则运算包含于闭包中.希望生成一个空间

image-20221127213110222 image-20221127213155596

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZqLfmpQ4-1678455927234)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221127213007817.png)]

看例题

模式分解

数据模型、关系模式、函数依赖、模式分解、无损连接 - 知乎 (zhihu.com)

把一个关系模式分解成若干个关系模式

等价分解定义:

  • 无损连接性:保证不丢失信息,可保证达到4NF
  • 保证函数依赖:解决操作异常问题,可保证达到3NF

第七章 数据库设计

数据库设计含义:

数据库设计是指对于一个给定的应用环境,构造(设计)优化的数据库逻辑模式和物理结构,并据此建立数据库及其应用系统,是指能够有效地存储和管理数据,满足各种用户的应用需求,包括信息管理要求和数据操作要求。

特点:

  1. 三分技术、七分管理、十二分基础数据。

    十二分基础数据强调数据的手机、整理、组织和不断更新是数据库建设中的重要环节。

  2. 结构设计和行为设计相结合

基本步骤:

  • 需求分析:准确了解与分析用户需求;设计基础
  • 概念结构设计:数据库设计的关键;通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型

三种数据抽象方法:分类(对元组进行分类)、聚集(对属性进行聚集)、概括

  • 逻辑结构设计:将概念结构转换为某个DBMS所支持的数据模型
  • 物理结构设计:选一个物理结构(存储结构和存取方法)
  • 数据库实施:用语言、工具建立数据库,调试程序、试运行等
  • 数据库运行与维护:正式运行、评价、修改

概念结构设计✨✨✨✨

局部ERD设计✨✨✨✨

ER模型:

  • 实体间的联系:一对一,一对多,多对多

实体是属性的集合

image-20221120185558736
  • 确定实体、实体的属性和实体的码
强实体和弱实体
强实体:不依赖于其他实体而独立存在的实体型
弱实体:必须依赖于其他实体才能存在的实体型
属主:被弱实体型所依赖的实体型称为标识属主,简称属主
弱实体型只有部分标识码,其属主的标识码与部分标识码共同构成弱实体型的完整标识码---标识码,标识实体的唯一编码
image-20221120173933477
  • 简单属性和复合属性
简单属性:单个元素构成的独立存在的属性,也成为原子属性
复合属性:多个元素构成的属性,其中每个元素都可独立存在
复合属性判定:用户是否要单独使用子属性?

ER图表示:用椭圆来描述复合属性的子属性,并置于所属复合属性的下方,用无向边将子属性与其所属的复合属性连接起来

主属性:属性名称下面加下划线

image-20221120174421960
  • 单值属性和多值属性

单值属性:每个实体在该属性上只有唯一属性值

多值属性:实体在该属性上可以有多个属性值

image-20221120174554004
  • 基属性和派生属性

派生属性(导出属性):可由其他属性值计算得到的属性

基属性(存储属性):不能由其他属性值导出的属性

image-20221120174754190
  • 确定实体及其属性的原则

适合性原则

简单原则:能抽象成属性的概念尽量不抽象成实体。一个关系表表现了一个实体对象

属性不能再用其他属性描述:如果属性需要进一步描述,则应将之抽象为实体

属性不能与其他实体发生联系

超类与子类

  • 确定实体间的联系

联系的基数约束

最大基础:对实体集A中的每个实体,实体集B中的最多有多少个实体与之对应,分为1:1, 1:N, M:M
最小基数:对实体集A中的每个实体,实体集B中的最少有多少个实体与之对应。若最小基数为0,则称B是可选的;若最小基数为1,则称B是强制的
image-20221120184458851
  • part-of联系
某个实体型是另外一个实体型的一部分
如:汽车实体和轮子实体,订单和订单明细
非独占part-of联系:部分实体可以独立存在
独占part-of联系:部分实体不能独立存在,也称为标识联系(弱实体型预与其属主间的依赖关系属于标识联系)
image-20221120185227978
  • 多元联系与关联实体
基数约束复杂
case工具
关联实体:增设关联实体,将多元联系转化为多个二元联系
ER图表示:带有矩形外框的菱形来表示关联实体
image-20221120185526423
  • 超类和子类的表示

    超类:包含一个或多个实体子集的实体型
    子类:实体集中某个实体自己的共同性质和特征的抽象
    超类/子类联系:联系类型为1:1
    分类属性:根据该属性的值,将实体分派到子实体型中
    分类属性标注在三角形旁边
    
    超类/子类联系的完备约束:
    		1、完全特化:超类中的每个实体必须属于某个子类的集合
    		2、部分特化:超类中的某个实体可以不属于任何一个子类型集合
    ER图中,双线表示完全特化,单线表示部分特化
    
    不相交约束和可重叠约束:约束超类中的实体是否可以同时属于多个子类。如果不可以,称该联系遵循不想交约束;相反,则遵循可重叠约束-----例如,学生只可能为本科生或研究生;某员工可能既是销售人员和管理人员
    ER图表示:可重叠约束不需要特别描述,不相交约束在超类和子类间的小三角中加上符号x来标识
    
    image-20221120185950173

    靠里是最小约束,靠外是最大约束,实体A与实体B的联系,是实体A向实体B伸出一只爪子的样子

    括号左边是最小基数,右边是最大基数

    image-20221120190904626

全局ERD设计:

冲突:产品和项目异名同义;冗余:仓库和职工联系包含在部门和职工联系中

  • 集成方式✨✨✨
    • 一次集成:适用于不太复杂的系统
    • 逐步集成:一次集成两个分ERD,逐步完成
  • 集成步骤
    • 消除冲突
    • 消除冗余
  • 消除冲突
    • 属性冲突:属性域(类型、值域)冲突,取值单位冲突
    • 命名冲突:同名异义,异名同义
    • 结构冲突:对象抽象方案不同,有的是实体,有的是属性,一般取实体;实体属性构成不同,一般取并集;联系类型不同,如联系的约束不同:取复杂方案
  • 消除冗余
    • 冗余类型:冗余数据 可由基本数据导出;冗余联系 可由基本联系导出
    • 消除方法:分析法;规范法
    • 保留冗余:定义完整性约束

ERD向关系模型转换

一、映射实体

  • 常规实体、关联实体及其属性

    • 实体属性和码就是关系的属性和码
    • 若包含复合属性,则将复合属性中的简单属性纳入到关系之中
    • 若包含多值属性,则另外在创建关系
    image-20221120193050979
  • 弱实体

    • 弱实体也转化为一个关系
    • 关系属性:属主的码、弱实体的所有简单属性、复合属性的组成部分转化为关系的属性
    • 主码和外码:属主的码+弱实体的部分标识符 构成关系的码,属主的码同时还是该关系的外码
    • 弱实体若包含多值属性,映射方法同理
    image-20221120194047874
  • 映射联系

重点在于实操和实例的复习,看ppt✨✨✨

书本p227以后

逻辑结构设计✨✨✨

**逻辑设计的任务:**把概念结构设计得到的ER图转换为具体DBMS支持的逻辑结构(含数据库模式和外模式)

模式结构在信息结构、完整性、一致性、可扩充性等访民安,均应满足用户的各种要求

ERD向关系模型转换:

  1. 映射实体:

    • 常规实体、关联实体及其属性

      • 一个实体转换为一个关系模式

      • 复合属性:只将构成复合属性的那些简单属性纳入到关系中,复合属性本身被抛弃

      • 若包含多指属性,则另外创建新关系

        一个多值属性对应一个新关系,由关系名反映多值属性的含义

        新关系的属性包含两部分:实体型的码和多值属性(全码)

        新关系的码:实体型的码和多值属性,实体型的码还是外码

        image-20221205172115787
    • 弱实体

      • 弱实体也转化为一个关系,弱实体名字就是关系名
      • 关系属性:属主的码,弱实体所有简单属性,复合属性转化
      • 主码和外码:属主码+弱实体部分标识码 构成码,属主的码同时还是该关系的外码
      • 弱实体的多值属性于常规实体相同处理
      image-20221205172635458
  2. 映射联系:(主要涉及如何处理联系的关系的码)

    • 映射1:1联系(任意一端作为关系的码)

      image-20221205173709671
    • 映射1:N联系(n端作为关系的码)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6aagxyu-1678455927234)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221205174400674.png)]

    • 映射N:M联系(实体本身一个关系,相关实体的码联合起来作为关系的码)

      image-20221205175322118
    • 映射多元联系ppt

      • 1:1:1 任意两个一端实体的码作为关系的码
      • N:1:1 N端加上任意1端实体的码作为关系的码
      • N:P:1 N端加上P端实体的码作为关系的码
      • M:N:P 三个实体的码作为关系的码
      • 使用关联实体映射多元联系
    • 映射超类和子类联系(N个子类、1个超类)

  3. 大型例题 ppt✨✨✨

物理设计

**物理结构:**指数据库在物理设备上的存储结构与存储方法

**物理设计:**为逻辑模型选取一个最适合应用要求的物理结构的过程

**考虑因素:**时间开销、空间开销、维护代价

**设计依据:**应用事务特点、DBMS特征

**存储访问:**文件(数据库被映射成一个或多个文件,由OS管理);块(每个文件被分成定长的存储单元,是存储分配和数据传输的单位);缓冲区(主存中存储磁盘块的部分);缓冲区管理器(负责缓存区空间分配的子系统)

**数据库的文件组织:**关系由文件存储,文件由DBMS管理

**文件组织形式:**堆文件组织(记录在文件中没顺序);顺序文件组织(根据搜索码顺序存储记录);Hash方法(指定关系的一个属性作为Hash码,对Hash码定义一个函数(Hash函数),记录的存储地址由hash(a)值决定, a是属性A的值);聚集文件组织(不同关系的记录可以存在同一文件中,不同关系中的相关记录可存储在相同物理块,有利于连接操作)

关系模式的存取方法选择

1.索引存取方法
经常出现在连接条件、查询条件中、经常通过聚集函数进行统计分析的属性(组)
2.hash存取方法
如果一个关系的属性主要出现在等值连接中或主要出现在等值比较选择条件中,且满足下列两个条件之一:
一个关系的大小可预知,而且不变
关系的大小动态改变,但数据库关系系统提供了动态hash存取方法
3.聚簇存取方法(根据关联关系,进行分组聚集存放)
为了提高某个属性的查询速度,把这个或这些属性上具有相同值的元组集中存放在连续的物理块中称为聚簇。该属性称为聚簇码。
适用于:经常进行连接操作的两个或多个关系;某个属性经常出现在比较条件中,可对单个关系建立聚簇;某个属性取值有一定重复度,可对单个关系建立聚簇
不适用于:经常进行全表扫描的关系;更新操作远远大于连接操作的关系;一个数据库可建立多个聚簇,但一个关系只能加入一个聚簇

sql sever存取方式

  • sql sever有两种数据组织:无序的堆组织;由聚簇索引决定单个关系中记录的物理排序
  • sql sever表创建主键时,会自动为主键建立唯一索引。若满足如下条件(这个表之前没有聚集索引;建立主键时,没有强制指定使用非聚集索引),该索引自动设为聚集索引
  • 创建聚集索引会导致现有非聚集索引全部重新组织一遍
  • sql sever的聚集索引对范围查询比较有用,只要找到边界值所在位置

确定数据的存储位置

  • 确定数据存放位置、存储空间大小:数据文件和日志文件的存储位置和文件大小;备份设备的存储位置;索引数据的存储位置;表分割存储
  • 确定系统配置参数
  • 数据库对象的存储位置策略:总目标——尽可能跨越多个设备,使数据访问分散到不同磁盘,多个IO运转,避免IO竞争

数据库的实施与维护

  1. 实施工作内容

    • 数据库及数据库对象的建立:编写DDL并执行
    • 数据载入:数据整理—录入—转换
    • 程序编码并调试
    • 试运行
  2. 数据库运行、评价、维护

    • 数据库转储和恢复

    • 数据库安全性与完整性控制

    • 数据库性能的监督、分析和改进

    • 数据库的重组织与重构造

      重组织:只改变数据的存放位置,重新组织存放(I\D\U操作数据碎片的产生使得效率下降)先卸载,再加载

      重构造:改变逻辑结构或物理结构(应用环境改变,需求变化等)

第八章 数据库恢复技术(填空、简答、概念)

事务的基本概念

  • 事务的定义

    用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。

  • 显式事务(多条语句构成)

    • begin transaction 显示开始

    • commit transaction

      rollback transaction 显示结束

  • 隐式事务(单条语句)

    • 系统自动开始
    • 提交或回滚

对上述事务,从begin开始,要么提交commit,要么报错回滚rollback

  • 事务的ACID特性(atom、consistent、independent、durable)

    (15条消息) 事务的ACID特性_你的破壁人呀的博客-CSDN博客

    • 原子性:是数据库的逻辑工作单元,要么都做,要么都不做
    • 一致性:使数据库从一个一致性状态变到另一个一致性状态
    • 隔离性:一个事务的执行不能被其他事务干扰。并发执行的各事务之间互不干扰。
    • 持续性:指一个事务一旦提交,它对数据库中的数据改变就应该是永久性的

    ACID可能遭到破坏的因素有:

    1. 多个事务并发运行时,不同事务的操作交叉执行,可能破坏隔离性(数据库管理系统需保证多个事务的交叉运行不影响这些事务的原子性)
    2. 事务在运行过程中被强制终止,可能破坏原子性、一致性等(DBMS必须保证被强行终止的事务对数据库和其他事务没有任何影响)

    以上就是DBMS中恢复机制和并发控制机制的责任

数据库恢复概述

故障种类

  • 事务内部的故障:事务未到达终点,数据库处于不正确状态

    • 可预期故障(如转账资金):应用程序处理//应用程序发现错误,并让事务回滚,撤销已做的修改
    • 不可预期故障(如运算溢出、死锁)//强行回滚的恢复操作称为事务撤销(undo)
  • 系统故障

    • 造成系统停止运转的任何事件,系统要重新启动
    • 所有活动事务都非正常终止
    • 已完成的事务,尚未写盘或部分写盘,数据不一致
    • 未完成的事务,已部分写盘,数据不一致

    对于事务尚未完成已送入物理数据库的部分,需要清楚这些事务的修改,事务回滚,强行撤销

    对于已完成的事务部分或全部留在缓存区,尚未写入磁盘/物理数据库,系统故障是缓冲区指令对数据库的修改丢失,需要将已提交的事务重写,即撤销未完成的事务,重做已提交的事务

  • 介质故障

    系统故障为软故障,介质故障为硬故障

  • 计算机病毒

故障原因:硬件故障、软件错误、误操作、恶意破坏;后果:数据库被破坏、数据库处于不一致状态

恢复的基本原理就是冗余

恢复的实现技术(冗余技术)✨

什么是数据库恢复?DBMS把数据库从错误状态恢复到某一已知的正确状态的功能就是数据库恢复/ 恢复原理:利用冗余恢复(下两个)

  • 数据库转储

    • 转储:将数据库定期复制到其他存储介质
    • 后备副本:转储出来的文件
    • 转储类型
      • 静态转储和动态转储(配合日志文件)
      • 海量转储(完全备份)和增量转储(差异备份,只备份更新的部分)
  • 登记日志文件

    数据库日志文件是记录事务对数据库所做的更新操作的文件

    • 日志的内容:各个事务的开始、各个事务的所有更新操作、各个事务的结束
    • 日志记录的格式:事务标识、操作类型、操作对象、更新前旧值、更新后旧值
    • 以数据块为单位的日志文件
    • 日志的作用:动态转储与恢复;事务内部故障恢复;系统故障恢复;介质故障恢复
    • 登记日志的原则:登记次序与并发事务执行的时间次序严格一致;先写日志原则
    • 日志文件同样需要转储,且转储频率应该更高

恢复策略

  • 事务故障的恢复:恢复子系统一个利用日志文件做undo撤销

    • 反向扫描日志文件(从最后向前扫描日志),查找该事务更新操作
    • 对事物的更新操作执行逆操作
    • continue
    • 直至事务开始标记
  • 系统故障的恢复:撤销未完成的事务(部分写盘,未写盘),重做已完成的事务(已写盘)

    内存缓冲区写盘:

    内存缓冲区(数据缓冲区,日志缓冲区)满
    遇到commit,往硬盘写日志
    遇到checkpoint(检查点)时,写日志和数据
    

    系统故障时,数据状态

    已完成事务
    日志:已写盘(完成的日志有commit,在硬盘中写入日志)
    数据:已写盘-ok,部分写盘-redo,未写盘-redo
    未完成的事务
    日志:部分写盘、未写盘
    数据:部分写盘-undo、未写盘
    
    • 不带检查点的恢复方法

      • 生成redo和undo队列
        • 正向扫描日志文件
        • 故障发生前已提交的事务,事务标识放入redo
        • 未提交的事务,放入undo
      • undo:逆向撤销处理【若数据写盘,日志一定也写盘】
      • redo:正向重做【已提交的事务,日志一定已写盘】

      注意:不带检查点的方法,首先当事务提交的时候,日志写盘;对于数据的写盘,需要在数据缓存区写满的时候,写盘(即写入数据库);当日志缓存区写满的时候,也会将日志写盘。

      image-20221206092007845

      其中,系统无法识别数据已经写盘和数据部分写盘、未写盘的区别,因此会全部重做,因此不带检查点的技术,方法效率低。

  • 介质故障的恢复

具有检查点的恢复技术✨

在日志文件中增加一类新的记录——检查点记录,增加一个重新开始文件,并让恢复子系统在登录日志文件期间动态地维护日志

image-20221123085107994

撤销操作是因为要保持事务的原子性,要么做完,要么不做

检查点:数据库正常运行的一个时间标志;在检查点时刻,系统强行将缓冲区内容写盘(也就是不等缓冲区满就写盘)

检查点的功能:系统强行将缓冲区内容写盘;记录检查点

检查点记录内容:建立检查点时刻,所有正在执行的事务清单;这些事务最近一个日志记录的地址

检查点执行的动作及其顺序

缓冲区中的日志写盘
在日志文件中,增加一个检查点记录
缓冲区中的数据写盘
重新开始文件新增一行,指示检查点在日志文件中的位置

恢复过程

在重新开始文件中,找最后一个检查点在日志中的位置
在日志中取最后一个检查点,得到活动事务清单放入undo_list
从检查点开始,正向扫描日志文件,遇到新开始事务加入undo_list,遇到结束的事务将其从undo_list移入redo_list
undo_list中的事务,做undo处理,从后向前
redo_list中的事务,做redo处理,从前向后

image-20221123092144440

介质故障✨

  1. 恢复最新的数据库备份副本
  2. 恢复日志文件副本
    • 重做已完成的所有事务
    • 撤销未完成的事务

数据库镜像

  • 数据库镜像:根据DBA的要求,自动把整个数据库或其中的关键数据复制到另一块磁盘,并自动维持二者的一致性
  • 写操作:更新主数据库时,自动将更新后的数据复制过去
  • 读操作:支持并行读出
  • 作用:提高可靠性

SQL SEVER的备份与恢复

SQL SEVER备份模式

  • 数据库完整备份:备份完整数据库,需要较大存储空间;还原数据库,只要还原一个备份文件即可
  • 数据差异备份:只备份上次完整备份后更改的数据
  • 日志备份:记录数据库的所有变动过程
  • 文件和文件组备份:创建数据库,若创建多个数据库文件或文件组,当某个文件损坏时,只需还原损坏的文件或文件组。

逻辑备份设备

  1. 逻辑备份设备
    • 为特定物理备份设备指定逻辑名称
    • 比物理长路径简单,无序更新脚本即可切换到新物理备份设备
    • 一个逻辑设备上,可以包含多个备份集
  2. 逻辑备份设备创建

备份数据库

backup database student to myBKD(备份设备) [with options]

backup database student to myBKD 
with init,name=N'学生数据库完整备份' 

备份日志

backup log student to myBKD
with noinit,name=N'学生数据库日志备份'

数据库恢复

/*数据库备份还原*/
restore database student
from disk=N'D:\stu.bak'
with file=1,norecovery,replace

/*日志备份恢复*/
restore log student
from disk=N'D:\stu.bak'
with file=3,recovery

第九章 并发控制

并发控制概述

多事务执行方式
  1. **事务串行执行:**串行执行
  2. **交叉并发方式:**其实就是并发方式(减少CPU的空闲时间,提高系统效率)
  3. **同时并发方式:**其实就是并行方式
  4. **并发控制:**用正确的方式调度并发操作,使一个事务不受另一个事务干扰,避免造成数据不一致
并发控制的必要性
  1. 并发操作带来的数据不一致

    • 丢失修改

    两个事务修改同一数据,导致一个事务的修改被另一个事务覆盖。

    • 不可重复读(不可再现)

    事务1读取数据后,事务2执行更新操作,使事务1无法再现前一次读取结果

    这两种不可重复读也称为幻影现象:事务2删除部分记录,事务1再读时,发现一些记录消失了;事务2插入数据时,事务1读取时,发现了一些记录。

    • 读“脏”数据

    事务读到的数据与数据库中的数据不一致,是不正确的,称为脏数据。

    如事务1修改了数据a->b,然后事务2读取了数据b,之后事务1回滚到数据a,此时事务2读的数据b与数据库中的数据是不同的

封锁及封锁协议

锁的基本概念
  1. 封锁:(访问某一共享数据,加锁,出来以后释放锁)事务在对数据对象操作之前,先向系统申请对该数据对象加锁,加锁后就对该数据对象有了一定的控制权,在释放锁之前,其他事务对该数据对象的使用(加锁将受到限制)
  2. **排他锁(写锁、X锁):**事务1对数据A加X锁,其他事务不能对A加任何锁(即事务1对资源A加了X锁,事务2获取了S锁需要等待A释放,而不能进行读取操作,这是符合实际的)
  3. **共享锁(读锁、S锁):**事务1对数据A加S锁,则其他事务只能对A加S锁,不能加X锁
image-20221206103505774
封锁协议✨✨✨

在使用锁时遵循的一些规则

常用的封锁协议:三级封锁协议 ppt例子

  • 一级封锁协议:事务1在修改数据A之前必须先对其加X锁,直到事务结束

    • 正常结束 提交
    • 非正常结束 回滚

    该协议可防止丢失修改(事务间的修改不冲突,串行修改,因此不会覆盖),读数据不需要加锁,不能保证重复读和不读“脏”数据(即其他事务修改了数据,无法保证事务1不读数据,从而读错误数据)

    X是修改锁

  • 二级封锁协议:一级封锁协议+事务1在读取数据A前必须先加S锁,读完后即可释放S锁

    • 可以防止修改丢失和读脏数据
    • 不能保证可重复读,因为读完数据后即可释放S锁,因此仍可能出现验证错误

    注意在对数据进行修改时,加了X锁,使得事务不能加任何锁,只有修改结束了以后,才能加S锁,即进行读的操作。但是无法改变事务2修改数据导致验算前后不一致,即两次读到的数据不同

  • 三级封锁协议:一级封锁协议+在事务1读取数据A之前必加S锁,直到事务结束才释放

    可以解决所有问题

image-20221128164258949

活锁和死锁

  • 活锁:某个事务请求封锁,但总也得不到锁,而处于长时间等待状态称之为活锁

线程间资源冲突,导致线程不断尝试都无法封锁,长时间等待

解决方法:先来先服务策略,多个事务请求封锁同一数据对象

  • 死锁:同时处于等待状态的多个事务中,每个事务在它能够继续执行之前,都在等待着对某个数据对象加锁,而这个数据对象已经被另一个等待的事务所封锁

意思就是多个事务相互占用对方的资源的锁,又互相等待对方释放锁

预防死锁的方法:

[SQL Server][转]数据库并发控制——活锁&死锁 - Angelo Dell’inferno - 博客园 (cnblogs.com)

  1. 一次封锁法

    每个事务必须一次将需要使用的数据全部加锁,否则就不能继续执行(这样就避免了资源相互调用的等待)

    缺点:降低并发度;确认全部数据困难

  2. 顺序封锁法

    预先对数据对象规定一个封锁顺序;所有事务按顺序封锁

    比如:事务1按照ABCD的顺序封锁,则事务1封锁了A时,事务2不能获取A锁,等待,指导获取A锁再继续进行。通过这种方式保证不发生死锁。

    缺点:维护成本高;难以实现,因为事务时动态变化的

死锁的诊断与解除:

  1. 允许死锁发生

  2. 检测并解除死锁

    • 由DBMS并发控制子系统定期检测
    • 检测到死锁,设法解除

    检测死锁:超时法

    优点:机制简单;缺点:时间设置,过短可能使长事务被误判为死锁

    检测死锁:等待图法✨✨✨

    图节点为事务,A指向B表示A等待B的锁释放

    如果有向图中存在回路(即相互等待的情况),则表明系统出现了死锁

    消除死锁

    事务开始时,赋予每个事务唯一的时标(应该是CPU占用时间,表示一个进程的代价)

    检测到死锁的回滚策略:选择一个处理死锁代价最小的事务,将其撤销,释放该事务持有的锁

    事务退回后重试,时标保持不变

并发调度的可串行性

**可串行化的调度:**即并发执行结果与按某一串行次序执行他们时的结果相同(注意是将事务串行)。注意串行次序指的时一个事务完成后完成下一个事务,如果通过排列组合能达到并发执行的结果,那么说明多个事务并发执行是正确的。毕竟并发是为了加快处理速度。

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

可串行化调度的判断

冲突可串行化是一个必可串行化更加严格的条件。会产生冲突的即在修改时发生,存在一个写操作。如果都是读操作并不会对数据产生影响

  1. 不同事务间的冲突操作
    • 不同事务对同一数据的写写操作:Wi(X)~wj(x)
    • 不同事务对同一数据的读写操作:Ri(X)~Wj(X)
  2. 不同事务间的非冲突操作
    • 不同事物对同一数据的读读操作
    • 不同事物对不同数据的任意操作

并发操作的可交换性

  1. 不可交换次序的操作
    • 不同事务的冲突操作
    • 同一事务的两个操作
  2. 可交换次序的操作
    • 不同事务的非冲突操作

可串行调度的判定方法(充分非必要条件)

对并发调度SC,保证冲突操作次序不变的情况下,若通过交换两个不冲突操作的次序,获得另一个串行调度SC‘’,则称Sc为冲突可串行化调度

  • 可串行化不好判定,而冲突可串行化有比较规范的判定方法
  • 若一个调度是冲突可串行化,则一定是可串行化的调度

可串行化调度的保障策略:两段锁协议

指的是事务必须分成两个阶段对数据进行加锁和解锁

在释放一个封锁后,事务不再申请获得其他封锁

  1. 第一阶段是获得封锁,也称扩张阶段(读写前加锁),此阶段可以获得任何锁,但不能释放锁
  2. 第二阶段是释放封锁,也称收缩阶段(释放锁后不能在申请锁),此阶段可以释放任意锁,但是不能获得锁

也就是说,锁不断增加和锁不断减少的过程

如 Slock A UnlockA SlockB XlockC UnlockC UnlockB 不遵守两端所协议

若在并发执行的所有事务都是遵循两段锁协议的,则对这些事务的任何并发调度策略都是可串行化的(充分非必要条件)

协议特点:保障可串行化调度的充分非必要条件

​ 注意与死锁预防策略的区别,两段所协议不能预防死锁

一次封锁法一定遵循两段锁协议,两端锁协议不一定遵循一次封锁法

封锁粒度及意向锁

**封锁粒度:**指封锁目标的大小

封锁对象:

  • 逻辑单元:属性值、属性值集合、元组、关系、索引项、整个索引、整个数据库。(数据库索引的作用就是提高查询数据的效率)
  • 物理单元:物理页、块、段、存取路径等。

封锁粒度的选择

粒度小:并行度高,效率高,系统开销大

粒度大反之

多粒度封锁:同时支持多种封锁粒度,供不同事务选择。使根据不同的事务特点选择使用,跟访问对象的粒度有关。大型DBMS一般均支持多粒度加锁。

多粒度树

多粒度封锁协议:允许多粒度树中每个节点被独立加锁

显示封锁和隐式封锁

显示封锁:应事务的要求,直接加到数据对象上的封锁

隐式封锁:某数据对象的上级结点加锁,从而使该数据对象加锁

多粒度封锁:冲突检查的复杂性

  • 本节点显示封锁:本节点的封锁与申请的冲突
  • 本节点隐式封锁:上级节点的封锁产生的隐式封锁,与当前的申请冲突
  • 下级节点显示封锁:本节点申请对下级节点产生的隐式封锁是否冲突

多粒度封锁的实现

  • 意向锁

    对某结点加意向锁,说明其下层节点正在被加锁

    意向锁的含义是如果对一个结点加意向锁,则说明该节点的下层结点正在被加锁;对任意结点加锁时,必须先对它的上层节点加意向锁

    常用意向锁有:

    • IS锁:意向共享锁,表示其后裔节点拟加S锁

      例如,事务T1要对R1中某个元组加S锁,则首先要对关系R1和数据库加IS锁

    • IX锁:意向排他锁

      同理

    • SIX锁:共享意向排他锁,表示对该节点加S锁,再加IX锁

      例如对于某个表加SIX锁,则表示该事务要读整个表,同时会更新个别元组

    相容矩阵 ppt

    数据库锁的相容性矩阵 解释 - 简书 (jianshu.com)

    两事务对同一对象加指定的锁是否可行的一个矩阵

    IX和IS的相容是重点。✨✨✨

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EyHuEbRv-1678455927235)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221128211246107.png)]

    处理顺序:自上而下申请,自下而上释放(对多粒度封锁而言的节点处理)

    例如,事务T1要对关系R1加S锁,则要首先对数据库加IS锁。检查数据库和R1是否已加了不相容的锁(X)。不再需要搜查和检查R1中的元组是否加了不相容的锁。

    具有意向锁的多粒度封锁方法提高了系统的并发度,减少了加锁和解锁的开销

    如关系的下一个节点可以是元组

    锁是用来保护并发性的,对于同一个事务锁显得没有必要

sql sever的封锁机制

事务类型

  • 系统提供的事务:一条语句就是一个事务
  • 用户定义事务:用begin transaction明确定义

事务影响的数据:行、多行、全部数据

**用户数据的空间管理:**行、页(8KB的空间)、簇(8页构成一簇,表和索引的最小占用单位)、表、数据库

**更新锁(U):**更新操作的初始阶段,页面被第一次读入时获得;在更改该页时,更新锁被提升为排他锁

image-20221128214637378

事务的封锁控制:

控制方式

  • 系统控制:悲观模式
  • 自主控制:乐观模式

建议:让系统自动管理锁

事务隔离级别:

  1. 可串行化:允许事务与其他事务并发执行,但系统必须保证并发调度时可串行化,不致发生错误
  2. 可以读未提交数据:一级封锁协议,允许事务读已提交或未提交的数据
  3. 读提交数据:二级封锁协议【默认设置】。允许事务读已提交的数据,但不要求“可重复读”
  4. 可重复读:三级封锁协议
  5. 快照隔离:改进死锁控制策略

第十章 关系查询处理和查询优化(不考)

查询处理方法

image-20221128174745139

选择操作的实现

  1. 简单的全表扫描方法
    • 对查询的基本表顺序扫描,逐一检查每个元组是否满足条件,把满足条件的元组作为结果输出。
    • 适合小表,不适合大表
  2. 索引(或散列)扫描方法
    • 要求:在where条件涉及的属性上建有索引
    • 通过索引先找到满足条件的元组指针,再通过元组指针在基本表找到元组

第十一章 数据库技术发展(不考)

扩张阶段(读写前加锁),此阶段可以获得任何锁,但不能释放锁
2. 第二阶段是释放封锁,也称收缩阶段(释放锁后不能在申请锁),此阶段可以释放任意锁,但是不能获得锁

也就是说,锁不断增加和锁不断减少的过程

如 Slock A UnlockA SlockB XlockC UnlockC UnlockB 不遵守两端所协议

若在并发执行的所有事务都是遵循两段锁协议的,则对这些事务的任何并发调度策略都是可串行化的(充分非必要条件)

协议特点:保障可串行化调度的充分非必要条件

​ 注意与死锁预防策略的区别,两段所协议不能预防死锁

一次封锁法一定遵循两段锁协议,两端锁协议不一定遵循一次封锁法

封锁粒度及意向锁

**封锁粒度:**指封锁目标的大小

封锁对象:

  • 逻辑单元:属性值、属性值集合、元组、关系、索引项、整个索引、整个数据库。(数据库索引的作用就是提高查询数据的效率)
  • 物理单元:物理页、块、段、存取路径等。

封锁粒度的选择

粒度小:并行度高,效率高,系统开销大

粒度大反之

多粒度封锁:同时支持多种封锁粒度,供不同事务选择。使根据不同的事务特点选择使用,跟访问对象的粒度有关。大型DBMS一般均支持多粒度加锁。

多粒度树

多粒度封锁协议:允许多粒度树中每个节点被独立加锁

显示封锁和隐式封锁

显示封锁:应事务的要求,直接加到数据对象上的封锁

隐式封锁:某数据对象的上级结点加锁,从而使该数据对象加锁

多粒度封锁:冲突检查的复杂性

  • 本节点显示封锁:本节点的封锁与申请的冲突
  • 本节点隐式封锁:上级节点的封锁产生的隐式封锁,与当前的申请冲突
  • 下级节点显示封锁:本节点申请对下级节点产生的隐式封锁是否冲突

多粒度封锁的实现

  • 意向锁

    对某结点加意向锁,说明其下层节点正在被加锁

    意向锁的含义是如果对一个结点加意向锁,则说明该节点的下层结点正在被加锁;对任意结点加锁时,必须先对它的上层节点加意向锁

    常用意向锁有:

    • IS锁:意向共享锁,表示其后裔节点拟加S锁

      例如,事务T1要对R1中某个元组加S锁,则首先要对关系R1和数据库加IS锁

    • IX锁:意向排他锁

      同理

    • SIX锁:共享意向排他锁,表示对该节点加S锁,再加IX锁

      例如对于某个表加SIX锁,则表示该事务要读整个表,同时会更新个别元组

    相容矩阵 ppt

    数据库锁的相容性矩阵 解释 - 简书 (jianshu.com)

    两事务对同一对象加指定的锁是否可行的一个矩阵

    IX和IS的相容是重点。✨✨✨

    [外链图片转存中…(img-EyHuEbRv-1678455927235)]

    处理顺序:自上而下申请,自下而上释放(对多粒度封锁而言的节点处理)

    例如,事务T1要对关系R1加S锁,则要首先对数据库加IS锁。检查数据库和R1是否已加了不相容的锁(X)。不再需要搜查和检查R1中的元组是否加了不相容的锁。

    具有意向锁的多粒度封锁方法提高了系统的并发度,减少了加锁和解锁的开销

    如关系的下一个节点可以是元组

    锁是用来保护并发性的,对于同一个事务锁显得没有必要

sql sever的封锁机制

事务类型

  • 系统提供的事务:一条语句就是一个事务
  • 用户定义事务:用begin transaction明确定义

事务影响的数据:行、多行、全部数据

**用户数据的空间管理:**行、页(8KB的空间)、簇(8页构成一簇,表和索引的最小占用单位)、表、数据库

**更新锁(U):**更新操作的初始阶段,页面被第一次读入时获得;在更改该页时,更新锁被提升为排他锁

image-20221128214637378

事务的封锁控制:

控制方式

  • 系统控制:悲观模式
  • 自主控制:乐观模式

建议:让系统自动管理锁

事务隔离级别:

  1. 可串行化:允许事务与其他事务并发执行,但系统必须保证并发调度时可串行化,不致发生错误
  2. 可以读未提交数据:一级封锁协议,允许事务读已提交或未提交的数据
  3. 读提交数据:二级封锁协议【默认设置】。允许事务读已提交的数据,但不要求“可重复读”
  4. 可重复读:三级封锁协议
  5. 快照隔离:改进死锁控制策略

第十章 关系查询处理和查询优化(不考)

查询处理方法

image-20221128174745139

选择操作的实现

  1. 简单的全表扫描方法
    • 对查询的基本表顺序扫描,逐一检查每个元组是否满足条件,把满足条件的元组作为结果输出。
    • 适合小表,不适合大表
  2. 索引(或散列)扫描方法
    • 要求:在where条件涉及的属性上建有索引
    • 通过索引先找到满足条件的元组指针,再通过元组指针在基本表找到元组

第十一章 数据库技术发展(不考)

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值