数据库系统概论

数据与信息的区别与联系?

  1. 数据(Data)必须保存在计算机中,能够被计算机识别、存储和处理。
  2. 信息(Information)是对数据的具体描述和语义化解释。
  3. 数据是信息的载体信息是数据的具体描述

数据库的定义、特征及辨析?

定义:数据库(DB)是长期储存在计算机内有组织可共享的大量数据的集合

特征:有组织、可共享、冗余度较低、易拓展。

辨析以下概念:

  1. DB:数据库
  2. DBMS:数据库管理系统
  3. DBA:数据库管理员

其中DBMS包含DB和DBA,属于系统软件。

数据模型是什么?数据模型有哪些?

数据模型是对现实世界数据特征的抽象和模拟。它的三个组成要素是:数据结构数据操作数据完整性

数据模型包括概念数据模型逻辑数据模型

  1. 概念数据模型是用户易于理解的、对现实世界数据特征的抽象。它与具体的DBMS无关。如实体—联系模型。
  2. 逻辑数据模型是用户从数据库中看到的,具体的DBMS所支持的数据模型。

逻辑数据模型主要有层次模型网状模型关系模型面向对象模型

  1. 层次模型用树形结构来表示各实体以及实体间的联系。每个结点表示一个记录类型,每个记录类型包含多个字段。
  2. 网状模型在层次模型的基础上,允许多个结点没有双亲结点和允许一个结点有多个双亲结点,最终的关系呈网状。
  3. 关系模型结合了层次模型和网状模型的优点,并有关系代数的支撑。

数据库管理系统的功能?

  1. DDL:对数据库的相关结构进行定义
  2. DML:对数据库中的数据进行插入、追加、修改、删除、检索等。
  3. DCL:对数据库中的数据进行控制,如并发控制、安全性控制、完整性控制等。

关系数据库的关系操作采用集合操作的方式,一次操作一个集合。

数据库的三级模式?

数据库的三级模式包括外模式模式内模式。它的一个主要目的是保证数据的独立性,包括逻辑独立性和物理独立性。

  1. 外模式是数据库用户可以看见和使用的局部数据的逻辑结构和特征的描述,可以简单理解为视图。一个数据库可以有多个外模式。
  2. 模式也称逻辑模式,是数据库中全体数据的逻辑结构和特征的描述,可以简单理解为表。它是三级模式的中间层,和应用程序无关,也和硬件无关,起到承上启下的作用。一个数据库只有一个模式。
  3. 内模式也称存储模式,描述的是数据库中数据存储的细节和存储路径,如记录数据是顺序存储,还是按照B树或hash方法存储。一个数据库只有一个内模式。

数据库的二级映射?

  1. 外模式/模式映射:如果模式改变时,只需要改变外模式/模式的映射,不需要改变应用程序。保证了逻辑独立性
  2. 模式/内模式映射:当数据的存储结构改变时,只需要由DBA对模式/内模式映射做出相应改变即可使模式不变。保证了物理独立性

关系模型和关系代数

关系模式与关系实例?关系的特点?

关系模式是对关系的描述与定义,关系模式的具体值就是关系实例,它是由若干列和行组成的表格,又是直接将关系实例称为”关系”。其中列称为属性,行称为元组。关系实例中元组的数目称为基数。特点如下:

  1. 每个关系都有一个唯一的关系名
  2. 关系表中的每一列都是不可再分的基本属性,各属性不能重名
  3. 一列中的所有值必须是同一数据类型,且必须有明确的范围(域)
  4. 关系中不允许出现相同的元组
  5. 行和列的排序对一个关系实例并不重要

关系可以表示为:关系名(属性1,属性2……属性n)

键/码?

关系中能唯一区分不同元组的属性或属性组称为关系的一个键或关键字或码。关键字对应的属性不能为空值,即不能为不确定的值。

与键相关的几个重要概念:

  1. 候选键:与上面键的定义一样,它满足唯一性最小性。(唯一性:不同元组,其候选键的属性值不同;最小性:任一属性都不能从属性集中删除)
  2. 主属性&非主属性:包括在候选键中的属性称为主属性,不包含在任何候选键中的属性称为非主属性。
  3. 全码:当所有属性都是候选键时,称为全码。
  4. 主键:从多个候选键中选择一个作为主键。每个关系有且仅有一个主键。
  5. 外键:F是关系R的某个属性,且不是R的键,但是F是另一个关系S的主键,则称F为关系R的外键。其中关系R称为参照关系,S称为被参照关系。(R和S可以为相同的表,即自约束)

关系的完整性约束?

关系模型中的完整性约束包括:实体完整性参照完整性用户定义的完整性。实体完整性和参照完整性是关系模型中必须满足的约束条件。

  1. 实体完整性:主键不能为空值,且取值唯一。
  2. 参照完整性:参照表R中外键的值,或者取空值,或者等于被参照表S中某个元组的主键值。
  3. 用户定义的完整性:根据应用环境和实际的需要定义的约束,如规定某个属性的取值范围,或某字段是否可为空等。

关系代数是什么?有哪些?

关系模型的常用关系操作包括查询操作更新操作。其中关系代数是关系模型的查询语言。关系代数的操作可以分为三类:

  1. 传统的集合运算:并、差、交、笛卡尔积
  2. 专门的关系运算:投影、选择、链接、除
  3. 拓展的关系运算:广义投影、聚集函数和分组、递归闭包

传统的集合运算?

两个关系进行并交差的前提是关系R和关系S具有相同的关系模式,即两个关系必须是同元(相容)的。它们以关系中的元组t为基本操作单位。

  1. 并运算:$R\bigcup S=\{ t | t\in R\lor t\in S\}$
  2. 交运算:$R\bigcap S=\{ t | t\in R\land t\in S\}$
  3. 差运算:$R - S=\{ t | t\in R\land t\notin S\}$

重点要理解笛卡尔积:R和S分别为m目和n目的关系,则RXS是一个(m+n)列,k1*k2个元组的集合:$R\times S=\{ \widehat{t_rt_s} | t_r\in R\land t_s\in S\}$

专门的关系运算?

  1. 选择:从关系R中找出满足给定条件F的所有元组t,相当于关系的水平切片:$σ _F (R)=\{t|t ∈R∧F(t)==True\}$,注意F的表示,如30岁以下的男性可以表示为 (性别=’男’)$\land$年龄<’30’。
  2. 投影:从R中选出若干属性列A组成新的关系,相当于关系的垂直切片。记作$∏_A(R)$,A为从R中选取的属性列的名字。
  3. 连接:连接运算从R和S的笛卡尔积中选择在R在A属性组的值与B属性组上的值满足比较关系的元组。
  4. 除:给出关系R(X,Y)和S(Y,Z),$P(x)=R÷S=\{t_r [X]|t_r∈R∧π_Y (S)⊆Y_x\}$ 。注意这里从元组中选出某一列用的是t[X]的方式,和从关系中进行投影不同。
  5. 更名:对给定关系代数表达式E ,进行更名运算$σ_x (E) $,返回表达式E的结果,并把名字x赋给了它。

重点要理解连接运算:连接分为两种,自然连接条件连接

  1. 自然连接:$R⋈S=\{t|\widehat{t_r t_s }|t_r∈R∧t_s∈S∧t_r [B]=t_s [b]\}$

    即比较R和S的公共属性。如果这个属性值相等,则将两个元组合并,并把重复的属性去掉。步骤为:

    • 计算$R\times S$
    • 选择R和S中公共属性属性相等的元组
    • 去掉重复属性

    如果两个关系没有公共属性,自然连接就是笛卡尔积。

  2. 条件连接表示R上的属性C和R2上的关系E在二者值相等时进行连接,为“等值连接”。除了=之外还可是其他条件。例子如下:

image-20220526083836044

需要注意自然连接和等值连接的区别:自然连接去掉了重复的列。

②理解除运算还需要知道几个相关的概念:

R表为:

pid did
206001 3501
206002 3501
206003 3502
206001 3502
206002 3502
206001 3503
  1. 分量:某一属性去掉相同的值后剩下的值,如上表pid可以取{206001,206002,206003}。
  2. 象集:对于关系R(X,Y),$Y_X$表示R中属性组X上值为x的诸元组在Z上分量的集合。如上表,206001的象集为{3501,3502,3503},206002的象集为{3501,3502},206003的象集为{3502}。
  3. 除运算的右边一般只有一列,和象集中的元素分量数保持一致。除的结果就是R中象集包含投影的所有分量。

S表为:

did
3501
3502

则R1 ÷ R2 = {206001,206002}。

再来看个例子:

image-20220526090206661

数据库设计过程和方法

数据库设计的概念?方法?步骤?

数据库设计是指对于给定的应用,构造最优的数据库模式来存储数据。包括结构设计(静态模型设计)和行为设计(动态模型设计)。

  1. 结构设计:数据库的概念设计、逻辑设计和物理设计。
  2. 行为设计:确定数据库用户的行为和动作。

数据库设计的方法有:直观设计法、新奥尔良设计法(规范设计法)、面向对象设计法和计算机辅助设计法。需要理解新奥尔良设计法,它包括需求分析概念设计逻辑设计物理设计四个阶段。

数据库设计的六个阶段:

  1. 需求分析
  2. 概念设计
  3. 逻辑设计
  4. 物理设计
  5. 实现和运行
  6. 维护

需求分析的方法?

进行需求分析的方法有结构化方法原型化方法数据流分析方法。常常将结构化方法和数据流分析方法结合,使用SA的自顶向下、逐层分解的方式来分析系统,使用数据流图(DFD)和数据字典(DD)来描述系统。

  1. 数据流图:描述信息在系统中流动和处理过程的图形化工具。用符号来表示数据的流动。
  2. 数据字典:对数据库中元数据的描述,而不是数据本身,相当于关系的属性,而不是关系实例。

概念设计的方法?

概念设计是从现实到信息世界的第一次抽象,并不考虑具体的DBMS。常常用实体-关系模型(ER图)来表示概念模型。ER图在下章介绍。

概念设计的方法有:自底向上自顶向下逐步扩张逐步混合

逻辑设计干什么?方法?

逻辑设计在概念设计的基础上,导出相应DBMS支持的数据库定义。它依赖于DBMS,实现E-R模式(实体、联系、键)到关系模式的转换。这个转换遵循实体转换规则联系转换规则

  1. 实体转换规则:实体的属性就是关系的属性,实体的键就是关系的键
  2. 联系转换规则:1:1、1:n、m:n不同关系的处理。

实体联系模型

实体联系模型的三个基本概念?

实体联系模型的三个基本概念为实体属性联系

  1. 实体:客观的事物。实体集则是具有相同属性实体的集合,如人就是一个实体集。实体集分为强实体集弱实体集

    强实体集:不依赖于其他实体集存在,每个实体都能由主键唯一标识

    弱实体集:每个实体不能由实体集的属性唯一标识。

  2. 属性:实体的特性,分为简单属性和复合属性、单值属性和多值属性、派生属性等。

    ①简单属性是不能再分的属性

    ②复合属性可以细分为更小的部分,如地址可以分为省、市等。

    ③单值属性只能取一个值

    ④多值属性可以取一个或多个值,如电话号码可以有多个。

    ⑤派生属性可以有其他属性推导出来,如由身份证号可以推出生日。

  3. 联系:实体间的关联。通常为动词,如患者和医生的联系为”就诊”。

多值属性常常进行变换

  1. 将一个多值属性用几个新的单值属性表示。如将电话号码细分种类。

    image-20220526095613003

  2. 将原来的多值属性用一个新的实体类型表示,这个新的实体类型为弱实体集,且和原来的实体集的关系为”拥有”。

    image-20220526095826679

ER图怎么表示实体、属性和联系?

  1. 实体方框表示,方框内注明实体的名称。
  2. 属性椭圆形框来表示,并且用无向边将属性对应实体连接起来。实体的主键用下划线来标注。

  3. 联系菱形框来表示,并且使用无向边来连接两个实体。

关系规范化

模式设计问题?

Dname Dlevel Dsalary Pname Fsum
罗晓 主任医师 3200 张珍 ¥30.00
杨勋 副主任医师 2800 张珍 ¥50.00
杨勋 副主任医师 2800 刘景 ¥55.00
杨勋 副主任医师 2800 张柳 ¥58.00
邓英超 主治医师 2400 李秀 ¥75.00
罗晓 主任医师 3200 傅伟相 ¥35.00

对于上面的关系,存在函数依赖

$F=\{\{Dname,pname \}\rightarrow Fusm,\\Dname\rightarrow Dlevel,\\Dlevel\rightarrow Dsal\}$

这就导致了数据冗余和可能发生操作(更新、插入、删除)异常的问题。

这时就需要将一个表拆分为多个表,即进行模式分解

image-20220526101929550

函数依赖是什么?怎么表示?分类?

数据依赖包含函数依赖(FD)、多值依赖(MVD)和连接依赖,是语义的体现。而函数依赖则体现的是一个关系中属性之间的联系

函数依赖的定义:X和Y是关系R的两个属性,t和s是R上的任意两个元组。如果$t[X]=s[X]\rightarrow t[Y]=s[Y]$,那么称Y函数依赖于X,或X函数决定Y,记作$FD\ \ X\rightarrow Y$。X为决定因子,Y为依赖因子。

①函数依赖分为平凡函数依赖和非平凡函数依赖。

  1. 平凡函数依赖:当$Y\subseteq X$时(注意X和Y可以是属性集),$FD\ \ X\rightarrow Y$恒成立。
  2. 非平凡函数依赖:一般指的函数依赖就是非平凡函数依赖。

②根据决定因子范围,非平凡函数依赖可以分为完全函数依赖部分函数依赖。完全函数依赖用来表明函数依赖的决定因子的最小属性集

image-20220526104145066

Y完全函数依赖于X的条件为:

  1. Y函数依赖于X
  2. Y不函数依赖于X的任何真子集

③根据函数依赖的传递性,分为传递函数依赖直接函数依赖

  1. 传递函数依赖:X、Y、Z是关系R的不同属性集,如果$X\rightarrow Y,Y\nrightarrow X,Y\rightarrow Z$,则称Z对X传递函数依赖。
  2. 直接函数依赖:如果$X\rightarrow Y,Y\rightarrow X$,那么Z直接函数依赖于X。

Amstrong公理怎解决的问题?怎么用?

Amstrong公理解决的问题是用一些已知的函数依赖去判断另外一些函数依赖是否成立,即逻辑蕴含问题

  1. 关系模式的多个函数依赖形成函数依赖集F。现在有一个新的函数依赖($X\rightarrow Y)$不在函数依赖集里,但能从集合里根据一定的规则推导出来,就说那个集合逻辑蕴涵这个新的函数依赖,用$F╞ X→Y$表示。

  2. 如果一个函数依赖能由现有的函数依赖集中的其他函数推出,则该函数依赖是多余的。

  3. 闭包(完备集)是指能由函数依赖集F推导出的所有函数依赖的集合。

Amstrong包含三个基本规则

  1. 自反性:如果$Y\subseteq X\subseteq U$,则$X\rightarrow Y$恒成立(平凡函数依赖)。
  2. 增广性:如果$X\rightarrow Y$成立,$Z\subseteq$ U,那么$XZ\rightarrow YZ$恒成立。
  3. 传递性:如果$X\rightarrow Y$且$Y\rightarrow Z$,那么$X\rightarrow Z$成立。

由此可得到的扩展规则:

image-20220526111123252

需要理解合并性、伪传递性、复合型。

可以保证由Amstrong公理推出的函数依赖是正确完备(可以推出所有逻辑蕴含的FD)的。

函数依赖的用途

(一)使用函数依赖来定义候选码和主码:设关系$R(U,F)$,$K\subseteq U$且,则K为候选码。若候选码多于1个,那么从多个候选码里面选择一个作为主码。

要注意候选码取自完全函数依赖集里面的属性,这样候选码就可以决定每个属性了。证明如下:

①由推理规则的分解性:$X\rightarrow \{A_1,A_2…A_n\}$,则$X\rightarrow A_i(i=1,2…n)$。(取完全函数依赖集里面的属性集)

②由推理规则的合并性:$X\rightarrow A_i(i=1,2…n)$,则$X\rightarrow \{A_1,A_2…A_n\}$。(这个属性集可以推出其他所有属性)

(二)由函数依赖定义外码

由函数依赖集F求最小依赖集G的算法?

  1. 根据分解性,使FD右边的属性均为单属性。删去重复的函数依赖。
  2. 根据传递性,删除冗余的FD。
  3. 看看能否消除左边冗余的属性。

image-20220526113817968

每个函数依赖集至少存在一个最小依赖集,但不一定唯一。

模式分解?怎么进行无损分解?

模式分解将一张冗余表分解为多张表。如果分解后的表通过自然连接能获得原始表,那么就是无损连接分解,否则称为损失分解

如$R(X,Y,X)$分解为$R1(X,Y)$和$R2(Y,Z)$,如果存在函数依赖$F={X\rightarrow Y,Y\rightarrow Z}$,则该分解是无损的。

无损分解的一个算法为追逐法

范式是什么?种类?怎么判断?

范式(NF)是一种关系的状态,是衡量关系模式好坏的标准

范式分为1NF、2NF、3NF、BCNF。我们需要掌握各范式的判断方法。

  1. 1NF:每个属性值都是不可再分的原子值,即不能”表中有表”。
  2. 2NF:关系模式R∈1NF,且每个非主属性完全函数依赖于候选码。如果主键只有一个,那么必定满足2NF;否则主键必须是函数依赖的最小属性集。
  3. 3NF:关系模式R∈1NF,且每个非主属性不传递依赖于候选码,而是直接依赖的。满足3NF的条件有两个:①R中的非主属性相互独立;②R中的非主属性完全函数依赖于主键。
  4. BCNF:关系模式R∈1NF,且 (包含主属性和非主属性)都不传递依赖于R的候选码。BCNF在3NF的基础上消除了主属性对码的可能存在的部分依赖和传递依赖。

2NF、3NF分解算法

(一)2NF分解算法

$R(Dname, Pname,Dlevel,Dsal,Fsum)$中,$Dname,Pname$是候选码,存在FD:$( Dname,Pname)→Fsum$和$Dname →(Dlevel,Dsal)$,后者是部分函数依赖,不满足2NF。

分解为两个表:

  1. $R1(Dname, Pname,Fsum)$,主键为$Dname,Pname$。这一步的属性取自部分函数依赖,主键取自部分函数依赖左边部分。
  2. $R2(Dname,Dlevel,Dsal)$,主键为$Dname$。这一步用U减去R1中的属性,如果是主键则需要考虑。

(二)3NF分解算法

$R2(Dname,Dlevel,Dsal)$存在$Dname →Dlevel$和$Dlevel→Dsal$,即存在传递函数依赖,不满足3NF。

传递函数依赖:$Dname\rightarrow Dsal$,中间属性为$Dlevel$,分解为两个表:

  1. $R1(Dlevel,Dsal)$,主键为$Dlevel$选择中间属性和传递依赖的右边,中间属性为主键。
  2. $R2(Dname,Dlevel)$,主键仍为$Dname$,外键为中间属性。

关于模式分解的几个事实?

  1. 若要求分解保持完全函数依赖,那么模式分解总可以达到3NF,但不一定能达到BCNF;

  2. 若要求分解既保持函数依赖,又具有无损连接性,可以达到3NF,但不一定能达到BCNF;

基础SQL语言

总的来说,SQL语言需要掌握以下9个动词:

  1. DDL:CREATE、DROP、ALTER
  2. DML:SELECT、INSERT、UPDATE、DELETE
  3. DCL:GRANT、REVOKE

数据库的创建和、修改和删除?

  1. 数据库的创建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE DATABASE <数据库名>
    [<On Primary>
    ([Name = 系统使用的逻辑名],
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]
    [<Log On>
    ([Name = 系统使用的逻辑名],
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [FileGrowth = 系统的扩展文件量])]

    要区别这里参数的含义,如NameFilename,前者指定的是逻辑名,后者指定的是文件名。可以缺省为CREATE DATABASE <数据库名>;

  2. 数据库的修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ALTER DATABASE <数据库名>
    [<Add File>
    (<Name = 系统使用的逻辑名>,
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]
    [<Modify File>
    (<Name = 系统使用的逻辑名>,
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]
    [<Remove File> <系统使用文件的逻辑名>,…]
    [<Add Log File>
    (<Name = 系统使用的逻辑名>,
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]

    可选的操作有<Add File><Modify File><Remove File><Add Log File>

  3. 数据库的删除DROP DATABASE <数据库名>;

表的创建、修改和删除

SQL SERVER中的数据类型

数据类型 申明
数字类型 NUMERIC, DECIMAL, INTEGER, SMALLINT, FLOAT, DOUBLE, REAL
字符串类型 CHAR, VARCHAR, TEXT
二进制串类型 BINARY, VARBINARY, BLOB
布尔类型 BOOLEAN
日期时间类型 DATE, TIME, DATETIME, TIMESTAMP
时间间隔类型 INTERVAL
  1. 表的创建:CREATE

    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE  基表名(
    <列名1> <列类型> <列约束>,
    <列名2> <列类型> <列约束>,

    <列名n> <列类型> <列约束>,
    <表约束> | [ { PRIMARY KEY | UNIQUE } [ ,…] ]

  2. 表的修改:ALTER

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ALTER DATABASE <数据库名>
    [<Add File>
    (<Name = 系统使用的逻辑名>,
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]
    [<Modify File>
    (<Name = 系统使用的逻辑名>,
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]
    [<Remove File> <系统使用文件的逻辑名>,…]
    [<Add Log File>
    (<Name = 系统使用的逻辑名>,
    [Filename = 完全限定的NT Server文件名],
    [Size = 文件的初始大小],
    [MaxSize = 最大的文件尺寸],
    [FileGrowth = 系统的扩展文件量])…]

    同样样注意namefilename

  3. 表的删除:DROP TABLE <表名>;

基本查询语句(重点)

查询语句的基本结构为:(需要记住顺序……不然考试可能扣分……)

1
2
3
4
5
6
7
SELECT [DISTINCT|ALL]{*|属性列表达式[AS 新的属性列名][,…] }
FROM <基表名|视图名>[别名][,…]
[INTO <新表名>]
[WHERE <行选择条件>]
[GROUP BY <分组依据列>]
[HAVING <分组选择条件>]
[ORDER BY <排序依据列>[ASC|DESC]];

顺序为:fromwheregroup byhavingorder by

Where后面的选择条件中,可以用的运算符:

  1. 比较运算符:=、!=或<>、<=、>=、<、>。
  2. 逻辑运算符:AND、OR、NOT。(优先级NOT>AND>OR)
  3. 集合运算符:IN、NOT IN
  4. 范围运算符:BETWEEN AND、NOT BETWEEN AND。
  5. 模糊查询:LIKE、_(下划线)、%(百分号)。
  6. 判空:IS NULL、IS NOT NULL。

其他:

  1. 聚集函数:SUM、COUNT、MAX、MIN、AVG

  2. ORDER BY语句分ASC升序DESC降序两种排序方式,默认升序。

  3. GROUP BY按照某列的值来分组,对其他列的选择必须使用聚集函数
  4. HAVING对分组进行过滤,后面的条件也要使用聚集函数。如果没有分组,则having等同于where。

对查询结果进行集合运算

  1. UNION实现集合并运算。
  2. EXCEPT实现差运算。
  3. INTERSECT实现交运算。

对查询结果进行连接

(一)内连接

  1. <表1> INNER JOIN <表2> ON <条件>

    1
    2
    SELECT Rno,Pno,D.Dno,Dname,Dsex,Dage,Ddeptno,Dlevel
    FROM RecipeMaster R JOIN Doctor D ON R.Dno = D.Dno
  2. <表1> INNER JOIN <表2> USING <列名>(两个表有相同名字的列):

    1
    2
    SELECT Rno,Pno,D.Dno,Dname, Dsex,Dage,Ddeptno,Dlevel
    FROM RecipeMaster R JOIN Doctor D USING(Dno)
  3. 等值连接where 表1.列1=表2.列2

  4. 自然连接NATURAL JOIN
  5. 自连接:需要使用别名来区分不同的副本。

(二)外连接

外连接分为左外连接右外连接全外连接三种。

  1. LEFT OUTER JOIN输出左表的所有记录相关列值,右表输出与左表匹配的记录,如果没有与左表匹配的记录,则使用NULL匹配输出。
  2. RIGHT OUTER JOIN输出右表的所有记录相关列值,左表输出与右表匹配的记录,如果没有与右表匹配的记录,则使用NULL匹配输出。
  3. FULL OUTER JOIN:左外连接和右外连接的并集。

事务与并发控制

事务的定义与特点?

事务是用户自定义的一个数据库操作序列。它可以显示定义,也可以缺省.

事务的特性包括ACID四个:

  1. 原子性:事务的操作要么全做,要么全不做。
  2. 一致性:当事务完成时,必须使所有数据都处于一致的状态
  3. 隔离性:事务并发执行时,一个事务的执行不能被其他事务干扰。
  4. 持续性:事务一旦提交,它对数据库的改变应该时永久性的。

事务并发执行可能带来的问题?

  1. 读脏数据:一个事务读取了另一个事务修改但未提交的数据。

    image-20220526144149208

    若一个事务写在另一个事务的读前面,则需要注意。

  2. 不可重复读:在一个事务内部前后多次读同一数据得到不一样的值

    image-20220526144619122

    若一个事务对同一数据进行多次读取,则需要注意。

  3. 丢失更新:一个事务的更新结果被另一个事务的结果覆盖,最后在数据库中没有得到体现。

    image-20220526144803707

​ 若一个事务的读在另一个事务的写之前,则需要注意。

可串行化调度是什么?有什么用?

两个事务的串行调度的方案有2!=2种:(n个事务的串行调度方式有n!种)

image-20220526145246363

这两种调度的顺序不同,最终写入数据库的结果也可能不同。但是我们认为这两种调度都是正确的,因为它保持了数据的一致性。

若多个事务交叉调度的结果某一个串行调度结果相同,那么就称这个调度是可串行化的。

可串行化的意义是,如果能证明一个调度是可串行化的,那么就能保持数据库的一致性,所以认为它是一个正确的调度

证明一个调度是否是可串行化,有冲突可串行化视图可串行化两种方案.

冲突可串行化?怎么判断?

从事务并发执行的问题可以看出,如果多个事务的对于同一数据的操作序列中相邻两个操作出现了写操作,那么这就是一个冲突的指令;如果只读不写,那么就是不冲突的。

image-20220526151036479

需要注意冲突是不同事务对于同一个数据的读写导致的,不同数据则一定不冲突。

我们将不同事务的非冲突指令交换顺序,若最终能化为串行调度,那么这个调度就是冲突可串行化的:

image-20220526151340014

冲突可串行化是该调度可串行化的充分条件。

使用前驱图可以方便的进行冲突可串行化的判定。前驱图中TiTj 的边表示在调度S中TiTj之间存在一对冲突指令,并且Ti中的指令先于Tj 中的指令执行:

image-20220526152254168

如果前驱图中存在环,那么就是不可串行化的,否则就是冲突可串行化。

image-20220526152431305

视图可串行化?怎么判断?

如果两个调度S1和S2在任何时候都保证每个事务读取相同的值写入数据库的最终状态也是一样的,则称调度S1和S2视图等价

image-20220526151557203

对于上面的两个调度,T1读取的都是数据库的初始值,T2读取的都是T1修改后的值,数据库中最终状态都是由T2写入,所以两个调度视图等价。

如果某个调度视图等价于一个串行调度,那么就称这调度视图可串行化

如果调度是冲突可串行化的,则它一定是视图可串行化的,反之不一定。

封锁?锁的分类?

确保事务隔离性的方法之一是要求对数据的访问以互斥的方式进行。即,当一个事务访问某一数据时,其它事务不能对该数据进行修改。实现该需求最常用的方法就是在访问数据前先持有该数据上的锁。

一个数据项的锁可以分为S锁和X锁

  1. 共享锁(S锁):只能读,不能写。
  2. 排他锁(X锁):可以读和写。

锁的相容矩阵如下:

image-20220526153116253

只有两个事务同时持有S锁时,才能对一个数据同时访问;否则后来的需要等待前面的事务释放锁后才能继续访问。

两段锁协议?

何时申请锁和释放锁的协议称为封锁协议。两段锁协议是一种比较常用的加锁协议。

  1. 增长阶段:在对任何数据进行读、写操作之前,首先申请并获得该数据的封锁。这阶段一直在加锁。
  2. 收缩阶段:在释放一个封锁后,事务不再申请和获得其它的任何封锁。这个阶段一直在释放锁。

两端锁协议是保证冲突可串行化的充分条件,但不保证不发生死锁

严格两段锁协议?

严格两段锁协议:除要求满足两段锁协议规定外,还要求事务的排它锁必须在事务提交之后释放

严格两段锁协议可避免级联回滚,同时解决了脏读和丢失修改的问题。

强两段锁协议?

强两段锁协议:除要求满足两段锁协议规定外,还要求事务的所有锁都必须在事务提交之后释放

在严格两段锁的基础上,进一步解决了数据项不能重复读的问题。

死锁的两种处理方式?

  1. 进行死锁的预防,不让并发执行的事务出现死锁的状况,方法有:
    1. 顺序封锁法
    2. 一次封锁法:事务在开始执行前先申请到所需的所有封锁
    3. 时间戳
  2. 允许死锁的发生,在死锁出现后采取措施解决

故障恢复

image-20220526154752479

后像后写?

后向后写是指后像在事务提交后才写入数据库。此时数据库恢复实行的是redo(重做)策略:重复执行已提交的事务,将所有的数据项设为新值;忽略未完成的事务。此时日志对写操作的记录为<T,X,V1>,V1为写入的新值。

恢复处理的步骤为:

  1. 从后向前扫描日志,将提交的事务放入队列redo-list(找提交操作命令)

  2. 从前往后扫描日志。对遇到的每一记录:

    1. 如果T不是redo-list中的事务,则什么也不做。
    2. 如果T是redo-list中的事务,则为数据项X写入值V1
  3. 对每个未完成的事务,在日志中写入一个记录并刷新日志

image-20220526155220794