依稀记得大二考数据库熬夜通宵复习完大早上直接去考试 结果只考了79分的痛QAQ
面试重点
总结自网络
参考:
BC范式和第三范式区别
解释范式
数据库的四个特性是什么?(类似地:解释事务的隔离性?
DBS 和 DBMS 的区别
数据库的索引有哪些分类
数据库中的选择操作,什么时候应该用到索引?
SQL一些语法
关系型数据库(RDBMS):建立在关系模型基础上,由多张互相连接的二维表组成的数据库
- 特点:使用表存储:格式统一;使用SQL语言操作:标准统一
分类
- DDL:数据定义(define)语言;定义数据库对象(数据库、表、字段)
- DML:数据操作(manipulation)语言;对数据库表的数据进行增删改
- DQL:数据查询(query)语言;查询数据库表的记录
- DCL: 数据控制(control)语言;创建数据库用户、控制数据库访问权限
DDL
操作数据库
(中括号代表可选)
1 | # 查询所有数据库 |
操作表
1 | # 查询当前数据库的 所有表 |
数据类型
char 和 varchar:
- char性能比varchar好
- char定长,varchar变长
日期类型:
- DATE、TIME、YEAR、DATETIME、TIMESTAMP
数据库安全性
指 DBMS应该保证数据库:免受非法、非授权用户的使用、泄露、更改和破坏
DBMS的安全机制分类
- 自主安全性机制:存取控制
- 通过权限在用户之间的传递,使用户自主管理数据库安全性
- 强制安全性机制
- 通过对数据和用户强制分类,使得不同类别用户能访问不同类别的数据
- 推断控制机制
- 防止通过历史信息,推断出不该被其知道的信息
- 防止通过历史信息推断出私密信息,通常在一些由个体数据构成的公共数据库中此问题尤为重要
- 数据加密存储机制
- 加解密保护数据
自主安全性机制
通过授权机制实现
- 授权者:决定用户权利的人;授权:授予用户访问的权利
用户使用DB前,必须由DBA处获得一个账户,由DBA授予该账户一定权限;
该账户用户也可将所拥有的权限转授给其他用户,实现权限在用户间的传播和控制
🛑 $\textcolor{red}{DBMS如何自动实现自主安全性?}$
- DBMS允许用户定义一些安全性控制规则(DCL)
- 当有DB访问操作时,DBMS自动按照安全性控制规则进行检查(安全性控制程序),检查通过则允许访问。
🛑 $\textcolor{red}{自主安全性访问规则}$
DBMS将权利和用户结合,形成一个访问规则表,依据该规则表实现对DB的安全性控制
1 | S这个用户对O这个访问对象,在满足在P这个条件下拥有的访问权利t: |
{AcessRule}
存放在数据字典 或称系统目录中,构成所有用户对DB的访问控制
🛑 $\textcolor{red}{下面是一个例子}$
对一个员工管理数据库Employee(Pno, Pname, Page, Psex, Psalary, Dno, HEAD)
有如下安全性访问要求:
S | O | t | P |
---|---|---|---|
员工管理人员 | Employee | 读、删、插、改 | |
收发人员 | Employee(Pname,Dno) | 读 | |
每个员工 | Employee | 读 | |
部门领导 | Employee | 读 | Pno=UserId |
高级领导 | Employee | 读 | Head=UserId |
🛑 $\textcolor{red}{按名控制安全性的实现方式}$
实现方式一:存储矩阵
实现方式二:视图
给不同用户用不同视图,就是相当于给与了不同的数据访问范围,相比矩阵更省空间
通过视图限制用户对关系中某些数据项的存取,例如
1
2视图1:create view EmpV1 as select * from Employee
视图2:create view EmpV2 as select Pname,Dno from Employee通过视图 可将数据访问对象和谓词结合起来,限制用户对关系中某些元组的存取,例如:
1
视图1:create view EmpV3 as select * from Employee where Pno=:UserId
用户定义视图后,视图便成为一新的对象,参与到存储矩阵与能力表中进行描述
用户与权利
🛑 $\textcolor{red}{SQL语言将用户分为三个级别}$
- 超级用户(DBA)
- 账户级别(程序员用户)
- 关系级别(普通用户)
🛑 $\textcolor{red}{SQL语言将权利分级}$
级别更高的权利自动包含级别低的权利;在有些DBMS中,将级别3的权利称为账户级别的权利,1和2称为关系级别的权利
- (级别1)
Select
:读(DB,Table,Record,Attribute…) - (级别2)
Modify
:更新Insert
、Update
、Delete
- (级别3)
Create
:创建(表空间、模式、表、索引、视图等)Create
、Alter
、Drop
DCL授权命令
🛑 $\textcolor{red}{授权:grant}$
1 | GRANT {all PRIVILEGES | privilege {,privilege..}} |
user-id
:某一个用户账户,由DBA创建的合法账户public
:允许所有有效用户使用授予的权利privilege
:这些权利:Select、Insert、Update、Delete、All privileges
with grant option
:允许被授权者在传播这些权利
❗ 授予视图访问的权利,并不意味着授予基本表的访问权利(两个级别:关系级别和视图级别)
🛑 $\textcolor{red}{收回授权:revoke}$
1 | REVOKE {all privilEges | priv {, priv..}} ON tablename | viewname |
🛑$\textcolor{red}{授权过程}$
- DBA创建DB,并为每个用户创建一个账户
- DBA授予某用户账户级别的权利
- 具有账户级别的用户可以创建基本表或视图,他也自动成为该表或该视图的属主账户,拥有该表或该视图的所有访问权利
- 拥有属主账户的用户可以将其中的部分权利授权给另外的用户,该用户也可将权利进一步授权给其他用户
强制安全性机制
🛑$\textcolor{red}{原理}$
- 通过对数据对象进行安全性分级
- 绝密(Top Secret)、机密(Secret)、可信(Confidential)、无分类(Unclassified)
- 同时对用户也进行上述安全性分级
- 从而强制实现不同级别用户访问不同级别数据的一种机制
🛑$\textcolor{red}{访问规则}$
- 高级别用户 可以访问 低级别数据对象:
- 用户S,不能读取数据对象O,除非
Level(S) >= Level(D)
- 用户S,不能读取数据对象O,除非
- 高级别用户 不可以修改 低级别数据对象
- 用户S,不能写数据对象O,除非
Level(S) <= Level(O)
- 用户S,不能写数据对象O,除非
嵌入式SQL语言
简述
特别复杂的检索结果难以用一条交互式SQL语句完成,此时需要结合高级语言中经常出现的顺序、分支和循环结构来帮助处理
将SQL语言嵌入到某种高级语言中使用,如C/C++, Java, PowerBuilder等,又称宿主语言(Host Language)
SQL执行的提交和撤销+事务
SQL执行过程中,必须有提交和撤销语句才能确认其操作结果
🛑$\textcolor{red}{事务}$
概念:(从应用程序员角度),事务是一个存取或改变数据库内容的程序的一次执行;或者说一条或多条SQL语句的一次执行被看作一个事务
由应用程序员提出,有开始和结束,结束前需要提交或撤销
1 |
概念:(从DBMS角度),事务是DBMS提供的控制数据操作的一种手段,通过这种手段,应用程序将一系列数据库操作组合在一起作为一个整体进行操作和控制,以便DBMS能提供移植性状态转换的保证。
🛑$\textcolor{red}{事务的特性:ACID}$
动态SQL
静态SQL: SQL语句在程序中已经按要求写好,只需要把一些参数通过变量传送给嵌入式SQL语句即可
动态SQL: SQL语句可以在程序中动态构造,形成一个字符串 ,然后再交给DBMS执行,交给DBMS执行时仍可以传递变量
数据字典
🛑$\textcolor{red}{概念}$
又称系统目录(目录表、系统视图),是系统维护的一些表或视图的集合,这些表或视图存储了数据库中各类对象的定义信息,这些对象包括用create定义的表、列、索引、视图、权限、约束等。这些信息又称为数据库的元信息(关于数据的数据;即 模式本身的信息)
🛑$\textcolor{red}{数据字典的内容构成}$
- 与关系相关的信息
- 关系名字、每个关系的属性名及类型、视图名字及定义、完整性约束
- 用户与账户信息,包括密码
- 统计和描述性数据:比如每个关系中的元组数目
- 物理文件组织信息
- 关系如何存储(顺序、无序、散列)
- 关系的物理位置
- 索引相关的信息
ODBC 和 JDBC
🛑$\textcolor{red}{ODBC}$
ODBC(open database connectivit开放式数据库连接)是一种 不同语言的语应用程序和不同数据库服务器之间通讯的标准,包含:
- 一组API,支持应用程序和数据库服务器的交互
- 应用程序通过调用 ODBC API,实现
- 与数据库服务器的连接
- 向数据库服务器发送SQL命令
- 逐条提取数据库检索结果中的元组传递给应用程序的变量
- 具体的DBMS提供一套驱动程序(Driver库函数),供ODBC调用,以便实现数据库和应用程序的连接
⭕ 当应用程序调用ODBC API时,ODBC API会调用具体DBMS Driver库函数,DBMS Driver库函数 与 数据库服务器通信,执行相应的请求动作并返回检索结果
🛑$\textcolor{red}{JDBC}$
简单了解,反正会用jiu’x🤣真想深入学就去看专门讲JDBC运用的视频
JDBC是一组Java版的应用程序接口API ,提供了Java应用程序与数据库服务
器的连接和通讯能力。
概念性的基本过程:打开一个连接,创建“Statement”对象,并设置查询语句,使用Statement对象执行查询,发送查询给数据库服务器,返回结果给应用程序;处理错误的例外机制
具体实施过程 :
传一个Driver给DriverManager,加载数据库驱动。
Class.forName()
通过URL得到一个Connection对象,建立数据库连接
DriverManager.getConnection(sDBUrI)
DriverManager.getConnection(sDBUrl,sDBUserlD,sDBPassword)
接着创建一个Statement对 象(PreparedStatement或CallableStatement),用来查询或者修改数据库。
Statement stmt=con.createStatement()
查询返回一个ResultSet.
ResultSet rs =stmt.executeQuery(sSQL)
关系数据库设计理论
包含:数据依赖理论、关系范式理论、模式分解理论
函数依赖
FD:Functional Dependence
参考书籍:《数据库系统基础教程》Jeffrey.D Ullman Jennifer Widom著
参考文章:
🛑$\textcolor{red}{函数依赖的定义}$
设$R(U)$是属性集合$U=\{A_1,A_2,\dots,A_n\}$上的一个关系模式,$X$,$Y$是$U$上的两个子集,若对$R(U)$的任意一个可能的关系$r$,$r$中不可能有两个元组满足在$X$中的属性值相等而在$Y$中的属性值不等(即:$X$中的每一个属性值,$Y$都有唯一值与之对应),则称 “$X$函数决定$Y$” 或者 ” $Y$ 函数依赖于$X$“,记作$X \rightarrow Y$。$X$为决定因素
两个属性(集)之间的取值关系,对于R(U),X、Y为属性集,t1、t2为R的元组,若t1[X]=t2[X],则t1[Y]=t2[Y]
例如:U = {学号,姓名,年龄,班号,班长,课号,成绩};那么:学号 → { 姓名,年龄 } :意思就是学号相同的话,那么姓名和年龄也一定相同;学号 决定 姓名+年龄
非平凡的函数依赖:对$X\rightarrow Y$,但$Y\not\subset X$,则称$X\rightarrow Y$为非平凡的函数依赖;反之,则是平凡的函数依赖
说人话:Y不是X的子集
平凡的函数依赖:
X 可以推导出自己或者自己的一部分
🛑$\textcolor{red}{完全函数依赖和部分函数依赖}$
在$R(U)$中,若$X\rightarrow Y$并且对于$X$的任何真子集$X’$都有$X’\nrightarrow Y$,则称$Y$完全函数依赖于$X$,记为$X \xrightarrow{f} Y $,否则称作Y部分函数依赖于X,记为$X \xrightarrow{p} Y $
说人话:完全函数依赖就是必须由X中的全部属性值 才能确定唯一的Y的值,X属性集中缺少任何一个属性 都不能 确定唯一的Y;
比如,想知道某位学生的某门课成绩Grade,必须得同时知道他的学号Sno和课程号Cno。如果只知道部分信息,比如只知道Sno或者Cno,无法确定Grade!此时 称Y[Grade]完全函数依赖于X[Sno,Cno]。
而想知道某位学生姓名Sname,那知道他的学号Sno就可。也就是Y[Sname]只函数依赖于X[Sno,Cno]中的子集x[Sno],此时称Y部分函数依赖于X
🛑$\textcolor{red}{传递函数依赖}$
在$R(U)$中,若$X\rightarrow Y,Y\rightarrow Z$ 且 $Y\not\subset X,Z\not\subset Y,Z \not\subset X,Y\nrightarrow X$,则称$Z$传递函数依赖于$X$
例如:知道一个学生的学号Sno,就能知道他所在的系Sdept。那知道某一个系Sdept,就能知道这个系的系主任的姓名Mname。
也就是,我知道了一个学生的学号Sno,其实我就知道了他所在系的系主任的姓名Mname。但这个过程中,他们是不存在直接函数依赖的,我需要通过系名称Sdept作为一个桥梁去把二者联系起来。
🛑$\textcolor{red}{函数依赖的几个重要概念}$
候选键(Candidate Key):设$K$为$R(U)$中的属性或属性集合,若$K \xrightarrow{f} U $,则称$K$为$R(U)$上的候选键(最小性+唯一性)
- 可以任选一候选键作为主键(Primary Key)
- 主属性:包含在任一候选键中的属性;其他称为非主属性
- 超键:若$K$是$R$的一个候选键,$S\supset K$,则称$S$是$R$的一个超键(即:一个包含键的属性集,没有最小性)
外键(Foreign Key):若$R(U)$中的属性或属性组合$X$并非$R$的候选键,但却是另一关系的候选键,则称$X$为$R$的外键
逻辑蕴涵:设$F$是关系模式$R(U)$中的一个函数依赖集合, $X, Y$是$R$的属性子集,如果从$F$ 中的函数依赖能够逻辑推导出$X \to Y$ ,则称$F$逻辑蕴涵$X \to Y$,或称$X \to Y$是$F$的逻辑蕴涵。记作$\mathbf{F} \models \mathbf{X} \rightarrow \mathbf{Y}$。
由已给出的函数依赖集,推导出其他函数依赖。推导出来的函数依赖就称作F所逻辑蕴涵的函数依赖。
就好像是侦探破案,掌握了几条线索,然后根据这几条线索推出来另外的线索,这另外推出来的线索就是之前线索集的逻辑蕴涵的线索。闭包(Closure):被$F$逻辑蕴含的所有函数依赖集合称为$F$的闭包,记作$F^{+}$
即:F中能所有的函数依赖 以及 能推导出来的所有的函数依赖 在一起的集合就是 F的闭包
若$F^{+}=F$,则称$F$是一个全函数依赖(函数依赖完备集)
🛑$\textcolor{red}{函数依赖的Armstrong公理}$
设$R(U)$是属性集$U=\{A_1,A_2,\dots,A_n\}$上的一个关系模式,$F$为$R(U)$的一组函数依赖,记作$R(U,F)$,有如下规则成立:
- 自反律:若$Y\subseteq X \subseteq U$,则$X \to Y$ 被 $F$ 逻辑蕴涵
- 增广律:若$X\to Y \in F$,且$Z\subseteq U$,则$XZ \to YZ$ 被 $F$ 逻辑蕴涵
- 传递律:若$X\to Y\in F$,且$Y\to Z$,则$X\to Z$ 被 $F$ 逻辑蕴涵
由$Armstrong$公理可推出如下结论(定理):
- 合并律:若$X\to Y$且$X\to Z$,则$X\to YZ$
- 伪传递律:若$X\to Y$且$WY \to Z$,则 $XW \to Z$
- 分解律:若$X\to Y$且$Z\subseteq Y$,则$X\to Z$
一个引理:
- 若$A_1,A_2,\dots,A_n$是属性,则$X\to A_1,A_2,\dots,A_n$当且仅当每个$A_i$有$X\to A_i(1\leq i\leq n)$
🛑$\textcolor{red}{覆盖和最小覆盖}$
覆盖:对$R(U)$上的两个函数依赖集合$F、G$,如果$F^{+}=G^{+}$,则称$F$ 和$G$ 是等价的,也称$F$ 覆盖$G$ 或者$G$ 覆盖$F$ 。
最小覆盖:若$F$满足以下条件,则称$F$为最小覆盖或最小依赖集:
- $F$ 中的每个函数依赖 的右部都是单个属性
- 对任何 $X\to A\in F$,有$F-\{X\to A\}$不等价于$F$:指 每个函数依赖$X\to A$ 都是不可获取的
- 对任何 $X\to A\in F,Z\subset X$,有$(F-\{X\to A\})\cup \{Z\to A\}$不等价于$F$:也就是说$X$ 中没有多余的属性
定理:每个函数依赖集$F$ 都有等价的最小覆盖$F’$
🛑$\textcolor{red}{属性闭包的计算}$
思想:从一个给定的属性集合出发,重复地扩展这个集合,只要某个FD左边的属性 全部 包含在这个集合中,就把此FD右边的属性也包含进去。反复使用这个方法,直到不再产生新的属性为止。最后的结果集合就是给定属性集合的闭包。
算法:
关系范式
范式(数据库的设计范式)是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式。关系数据库中的关系必须满足一定的要求,即满足不同的范式
第一范式:1NF
🛑$\textcolor{red}{定义}$
若关系模式$R(U)$中,关系的每个分量都是不可再分的数据项(值、原子),则称$R(U)$ 属于第一范式,记作$R(U)\in 1NF$
例如:Star(name, address(street, city))
就不属于第一范式,因为address
包含两个属性,这个分量不是原子的,可以再分
🛑$\textcolor{red}{非1NF转换为1NF}$
- 将复合属性处理为简单属性;将多值属性与关键字单独组成一新的关系
- 引入新的数据模型处理:面向对象的数据模型(封装)
第二范式:2NF
🛑$\textcolor{red}{定义:1NF+消除非主属性对码的部分依赖}$
若$R(U)\in 1NF$ 且$U$中的每一非主属性都完全函数依赖于候选键,则称$R(U)$属于第二范式,记作$R(U)\in 2NF$
2NF要求数据库表的每个实例或行 必须可以被唯一地区分。不能存在仅依赖主关键字一部分的属性。如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系
第三范式:3NF
🛑$\textcolor{red}{定义:2NF+消除非主属性对码的传递依赖}$
若$R(U,F)\in 2NF$且$R$ 中不存在这样的情况:候选键$X$,属性组$Y\subseteq U$和非主属性$A$,且$A\notin X, A\notin Y,Y\not\subset X,Y\not\to X$,使得$X\to Y,Y\to A$成立。满足上述条件的$R(U)$属于第三范式,记为$R(U)\in 3NF$
3NF要求一个数据库表中 不包含 已在其它表中已包含的非主关键字信息。
Boyce-Codd范式
🛑$\textcolor{red}{定义:3NF+消除主属性对码的部分和传递依赖}$
若$R(U,F)\in 1NF$,若对任何$X\to Y\in F$(或$X\to A\in F$),当$Y\not\subset X$(或$A\not\subset X$)时,$X$必含有候选键,则称$R(U)$属于BC范式,记为:$R(U)\in BCNF$
每个非平凡函数依赖的左边都必须包含键(可以是超键,不一定要最小化)
有传递依赖的,或者说不满足3NF的,也一定不满足BCNF
多值依赖
模式分解
索引
基本介绍
🛑$\textcolor{red}{定义}$
索引是定义在存储表(Table)的基础上,有助于 无需检查所有记录而快速定位所需记录的 一种辅助存储结构。由一系列存储在磁盘上的索引项组成,每一索引项分成以下两部分:
- 索引字段:由Table中某些列中的值串接而成。索引中通常存储了索引字段的每一个值(也有不是这样的),类似于词典中的词条
- 行指针:指向Table中包含索引字段值的记录在磁盘上的存储位置,类似于词典中的页码
索引文件:存储索引项的文件;主文件:存储表
索引文件是一种辅助存储结构,存在与否不改变存储表的物理存储结构;存在就可以明显提高存储表的访问速度:索引文件比主文件小很多,可以全部装进内存
有索引时,更新操作必须同步更新索引文件和主文件
排序码:对主文件进行排序存储的那些属性或属性组
索引码:即索引字段,不一定具有唯一性
搜索码:在主文件中查找记录的属性或属性集
🛑$\textcolor{red}{索引文件的组织方式}$
- 排序索引文件:按索引字段值的某一种顺序组织存储
- 散列索引文件:依据索引字段值使用散列函数分配散列桶的方式存储
稠密索引和稀疏索引
🛑$\textcolor{red}{定义}$
稠密索引:对于主文件中的每一个记录,都有一个索引项与之对应,指明该记录所在位置
稀疏索引:部分记录
稠密索引文件中 包含了主文件对应字段的所有不同值
稀疏索引的使用:要求主文件必须按对应索引字段属性排序存储
主索引和辅助索引
🛑$\textcolor{red}{主索引}$
通常是对每一存储块有一个素引项 ,索引项的总数和存储表所占的存储块数目相同,存储表的每一个存储块的第一条记录,又称为锚记录或简称为块锚
主索引的索引字段值为块锚的索引字段值,指针指向其所在的存储块。
主索引是按索引字段值进行排序的一个有序文件,通常建立在有序主文件的基于主码的排序字段上,即主索引的索引字段与主文件的排序码(主码)有对应关系主索引 是稀疏索引
🛑$\textcolor{red}{辅助索引}$
是定义在主文件的任一或多个非排序字段上的辅助存储结构
聚簇索引和非聚簇索引
🛑$\textcolor{red}{聚簇索引}$
索引中邻近的记录在主文件中也是邻近存储的
🛑$\textcolor{red}{非聚簇索引}$
索引中邻近的记录在主文件中不一定是邻近存储的
B+树索引
多级索引:对索引再建立索引
🛑$\textcolor{red}{定义}$
B+树的每一个结点都是如下这样的存储块:
$P_1$ | $K_1$ | $P_2$ | … | $P_{n-1}$ | $K_{n-1}$ | $P_{n}$ |
---|---|---|---|---|---|---|
$K_i$:索引字段值
$P_i$:指针,指向索引块或数据块或数据块中记录的指针
- 一个存储块中有$n-1$个索引项$
$ + $1$个指针$P_n$ - 索引字段值$x$,若$K_{i-1}\leq x\lt K_i$的由$P_i$ 指向;在$K_{i}\leq x\lt K_{i+1}$的由$P_{i+1}$指向
- 非叶结点:指针指向索引块
- 叶结点:指针指向主文件的数据库或数据记录(叶结点的最后一个指针始终指向其下一个数据块)
🛑$\textcolor{red}{B+树的两个特性}$
- 能自动保持与主文件大小相适应的树的层次
- 每个索引块的指针利用率都在50%-100%之间
🛑$\textcolor{red}{B+树的存储约定}$
- 索引字段值重复出现于叶结点和非叶结点
- 指向主文件的指针 仅出现在 叶结点
- 所有叶结点 即可覆盖所有键值的索引
- 索引字段值在叶结点中按顺序排列
Hash索引
事务
什么是数据库的事务?
🔸 DB的事务是一个不可分割的数据库操作序列,也是DB并发控制的基本单位;这组逻辑上的操作要么都执行,要么都不执行;其执行的结果必须使DB从一种一致性状态变到另一种一致性状态。
将一系列数据库操作组合在一起,作为一个整体进行操作和控制
从应用程序员角度:事务是一个存取或改变数据库内容的程序的一次执行;或者说一条或多条SQL语句的一次执行被看作一个事务;由应用程序员提出,有开始和结束,结束前需要提交或撤销
在嵌入式SQL程序中,任何一条数据库操纵语句(如exec sql select等)都会引发一个新事务的开始,只要该程序当前没有正在处理的事务。而事务的结束是需要应用程序员通过commit或rollback确认的。因此Begin Transaction 和End Transaction两行语句是不需要的。
1 | Begin Transaction |
什么是数据库的四大特性ACID?
🔸 原子性(Atomicity):DBMS保证事务的一组更新操作是原子不可分的,确保操作要么全做,要么全不做
事务中任何一个sql执行失败,那么执行成功的sql也必须撤销,数据库状态回退到执行事务之前的状态
🔸 一致性(Consistency):事务执行前后,所有数据都必须处于一致性状态,多个事务对同一个数据读取的结果是相同的
比如:假设用户A和用户B的钱加起来一共5000,那不管A和B之间如何转账,转账几次,事务结束后两个用户的钱加起来应该还是5000,这就是事务的一致性。
🔸 隔离性(Isolation):DBMS保证并发执行的多个事务之间互相不受影响。
一个事务内部的操作及正在操作的数据 对 其他并发执行的事务是隔离的。例如事务T1和T2即使并发执行,也相当于先执行T1,再执行T2(或者相反
🔸 持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
事务的并发会带来什么问题?如何解决?
🔸 脏读:一个事务读取到另一个事务更新但尚未提交的数据。
事务 A 读取事务 B 更新的数据,然后 B 回滚操作,那么 A 读取到的数据是脏数据。
T1修改某个数据,并将其写回磁盘,T2读取之后,T1由于某种原因被撤销,这时T1已修改过的数据恢复原值,导致T2读脏数据
🔸 不可重复读:一个事务中两次读取的数据的内容不一致
T1读取数据后,T2执行更新操作,T1再次读取时,无法再读到之前的数据
🔸幻读:一个事务中两次读取的数据量不一致。 事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据
当同一条查询在不同的时间产生不同的结果集
🔸丢失更新:两个事务读入同一数据并修改,后一提交的事务会覆盖前一事务提交的结果,就会导致前一事务的修改被丢失。