数据库
数据库系统相关概念
数据:符号序列,是计算机能够识别、存储、处理的描述。
信息:数据的含义
数据处理:数据—>信息的过程
数据库:长期存储在计算机内,有组织,可共享的大量数据的集合
数据库管理系统(DBMS):用户与数据库之间的管理软件。它提供了:
数据定义功能(数据定义语言DDL)
数据操纵功能(数据操纵语言DML)
数据控制语言(数据控制语言DCL)
数据组织、存储、管理功能
数据库建立维护功能
数据库系统的组成
硬件系统
数据库集合
系统软件
数据库管理员
用户
数据库系统有如下功能:
定义数据库
查询数据库
更新数据库
多用户访问
存储大量数据
数据库系统特点
数据结构不是面向单一应用,而是面向全组织
数据冗余小、易扩充
数据独立程序
统一的数据管理功能
数据安全控制
数据完整性控制
数据的并发控制(解决多用户情况)
数据库管理阶段
人工管理阶段
文件系统阶段
数据库系统阶段
模型
概念模型: 按照用户需求对数据库和信息进行建模,涉及实体、属性、联系等概念
实体:客观存在且可相互区分的事物
属性:实体具有的特性
联系:实体之间的关联关系。联系涉及的概念:
1.度:参与联系的实体的个数。
2.角色名称:实体在联系中扮演的角色
3.递归关系:同一实体以不同的角色名称参与到同一联系中
4.基数比:一对一、一对多、多对多
5.联系约束:约束参与联系的实体的集合,分为:
- 基数比
- 参与约束
6.参与约束:每个实体所能参与联系的最小个数
- 完全参与约束也称存在依赖,每个实体都要遵循
- 部分参与约束
数据模型
数据模型的基本要素
- 数据结构
- 数据操作
- 数据完整性约束
数据的逻辑模型,省略数据存储的细节,主要用于DBMS的实现,分以下类别:
层次模型(实体之间联系用树形结构表示)
网状模型(实体之间的联系用有向图表示)
- 关系模型(实体之间的联系由表来表示)
- 面向对象模型(把实体表示为类,对象中包含了对象内元素的联系和对象之间的联系)
物理模型
- 数据在计算机中存储的具体细节,能够由DBMS理解的模式
三层模式结构
外部层含外模式(视图)
外部层包含很多外模式,描述特定的数据库
概念层含概念模式(关系)
概念层有一个概念模式也称模式,描述数据逻辑,实体、数据类型、用户操作、约束、安全性和完整性信息
内部层含内模式(索引)
内部层有一个内模式,描述数据库物理储存结构
数据库语言
数据查询语言(DQL): 数据查询
数据定义语言(DDL): 定义数据结构,创建、修改、删除数据库
数据操纵语言(DML): 追加、插入、删除、修改、检索数据
数据控制语言(DCL): 控制数据库权限、事务发生时间、监视数据库
SQL:关系数据库的标准语言,非过程化。
数据库管理员(DBA)的职责
- 定义并存储数据库内容
- 监督和控制数据库使用
- 负责数据库的日常维护
- 必要时重组、改进数据库
关系数据模型
关系数据模型主要由:关系数据结构、关系数据操作、关系完整性约束组成。
关系需要满足的条件、性质:
- 每一列都不可再分(原子性)
- 属性名不可重复
- 表中元组的顺序可以调换
- 同一属性名下的属性应该在同一域中,是同一数据类型
- 元组不能重复
关系的类型:
- 基本关系:实际存在的表,是数据的逻辑表示
- 查询表:查询结果对应的表
- 视图表:是基本表或其他视图表导出的虚表,不存储数据
元组:关系的一行
属性:关系的一列
域:属性的取值范围,是一组具有相同数据类型的值的集合
基数:域中包含值的个数
度:表长
分量:元组中的一个属性值
键:唯一区分不同元组的属性或属性的集合
候选键:唯一区分不同元组的属性或属性的集合
主键:候选键中选取的一个作为关系的主键
主键唯一
每个关系必须有且只有一个主键
外键:属性(属性组)F不是关系R的键,但F却是关系S的主键,则属性F是关系R的外键。
关系R:参照关系
关系S:被参照关系
R和S可以是同一个关系
S的主键和F必须在同一域上
关系
笛卡尔积有意义的子集,是一张2维表
关系模式:一般表示为:
R(U,D,DOM,F)
R:关系名
U:属性名
D:U中属性的域
DOM:属性向域的映射集合
F:数据依赖关系的集合
关系完整性:
- 实体完整性:主键唯一且非空
- 参照完整性:外键要么为空,要么是另一个关系的主键
- 用户自定义完整性、
- (空值)
数据操作(为集合操作的方式)
关系代数:代数方式
关系演算:逻辑方式
关系代数(抽象 )
关系运算符:
集合运算符
比较运算符
关系运算符
逻辑运算符
关系代数的操作:
集合运算:并、差、交、笛卡尔积
关系运算:投影、选择、连接、除、更名
扩展的关系运算:广义投影、聚集函数、分组、递归闭包
专门的关系运算
选择运算($\sigma$):选择符合条件的元组组成新的关系。取R中符合条件的元组:
$\sigma_{条件}(R)$
投影运算($\pi$):选择符合条件的属性组成新的关系。取关系R的第i、j列:
$\pi_{i,j}(R)$
连接运算($\infin$)
自然连接:$R_1\infin R_2$
- 计算关系间的笛卡尔积
- 选择在两个关系中属性相等的元组
删除重复属性
外连接
条件连接:$R|\times|S_{条件}$
$\sigma_{条件}(R\times S)$
除运算($\div$)
$A(x, y)\div B(y,z)$
- 找出x的域,对应每一个x取值,求出对应的象集t
- 求出投影$\pi_y(R_2)$
- 找出t中包含投影的值,即为除运算结果
更名运算($\rho$)
$\rho_{新表名(新属性名)(R)}$
SQL
sql提供的功能
- 数据定义功能(DDL)
- 数据操纵功能(DML)
- 数据控制功能(DCL)
- 数据查询功能(DQL)
sql的特点
- 非过程化语言
- 统一的语言
- 面向集合的操作方式
- 可独立使用又可嵌入主语言使用
操作对象 | 创建 | 修改 | 删除 |
---|---|---|---|
数据库 | create database | alter database | drop database |
表 | create table | alter table | drop table |
视图 | create view | drop view | |
索引 | create index | drop index |
在表中插入元组:
1 |
|
更新表数据:
1 |
|
删除表元组
1 |
|
修改表的命令:
1 |
|
查询表的命令:
1 |
|
WHERE后接判断:
属性 [NOT] BETWEEN constant1 AND constant2
属性 [NOT] LIKE 字符串或通配符
属性 IS [NOT] NULL
属性|常量 [NOT] IN (SELECT 子句)|元组
[NOT] EXITS (SELECT 子句)
LIKE 匹配的通配符
聚集函数(只能出现在select、having中,不能在where中出现)
出现在分组依据中的属性名不能出现在聚集函数中
聚集函数使用 | 意义 |
---|---|
count(*) | 统计属性元组个数 |
count([DISTINCT] 属性名) | 统计属性名下[不重复]的非空分量个数 |
sum([DISTINCT] 属性名) | 对属性名下所有[不重复]分量求和 |
avg([DISTINCT] 属性名) | 对属性名下所有[不重复]分量均值 |
max(属性名) | 求属性列下最大值 |
min(属性名) | 求属性列下最小值 |
分组
除聚集函数之外,select中出现的属性必须来自group by中的属性列
连接查询
连接操作执行的方法:
- 循环嵌套法
- 排序合并法
- 索引连接法
连接方式
内连接
- FROM table1 JOIN table2 ON <连接条件>
- WHERE <连接条件>
- 自然连接
自连接
同一张表内子表之间的连接查询
外连接
SQL SERVER
1
2
3
4
5
6SELECT <查询列表>
[INTO <新表名>]
FROM <table1|view1> [AS new_name1]
<LEFT|RIGHT|FULL>[OUTER] JOIN>
<table2|view2> [AS new_name2]
ON <连接条件>WHERE A (+)= B #ORACLE数据库左外连接
WHERE A =(+) B #ORACLE数据库右外连接
LEFT OUTER JOIN: 左外连接
输出左表所有记录列值,右表输出与左表向匹配的记录,没有输出NULL
RIGHT OUTER JOIN:右外连接
输出右表所有记录列值,左表输出与右表向匹配的记录,没有输出NULL
FULL OUTER JOIN:全连接
$left_outer_join \cup right_outer_join$
TOP限制结果集
1
SELECT TOP n [WITH TIES] <column_name>
- 使用 WITH TIES会将并列值捆绑,同时输出,并算作同一排名
ANY ALL
ANY: 至少一个值要满足条件
ALL:所有值都满足条件
- eg.找出年龄大于所有女性的男性客户
1
2
3select name, age
from user
where sex='male' and age > ALL(select age from user where sex='female');
视图
定义
1 |
|
以下情况需要指定view list:
- 子查询中有聚集函数或者列表达式
- 多表连接出现相同属性名
- 需要给属性更名
子查询限制:
不能含有ORDER BY
不能含有DISTINCT
删除
DROP VIEW view_name [CASCADE];
- 加CASCADE后会联级删除该视图与其导出的所有视图
查询
与关系的查询相同
更新
只有满足以下所有条件的视图才能对基表进行更新操作:
- 视图只定义在一个基表上
- 子查询不含 GROUP BY、DISTINCT、聚集函数
- 视图列不含计算表达式
- 视图列包含所有基表中NOT NULL的列
作用
- 视图能简化用户操作
- 视图对重构的数据库提供一定程度的逻辑独立性
- 视图为用户提供多个视角看同一数据
- 提高数据安全性
- 保证数据完整性
索引
特点:空间换时间(hash)
分类
聚簇索引
索引与数据储存在相邻等待数据空间,并使行的物理顺序和索引的顺序一致
对经常搜索范围值的列非常有效
非聚簇索引
数据和索引分开存储,索引以指针指向数据
精确匹配查询最佳方法
唯一索引
保证索引列不含重复值
创建PRIMARY KEY或UNIQUE约束会自动在表上场景唯一索引
创建
1 |
|
删除
1 |
|
索引建立原则
- 选择数据量大的表建立索引
- 索引建立数量要适量
- 选择合适时机建立索引
- 优先选择主键建立索引
- 为支撑连接操作,考虑在外码上建立非聚簇索引
- 最好选择包含大量非重复值的列建立非聚簇索引
SQL server的三类操作系统文件
- 主文件 .mdf: 数据库启动信息及数据信息,每个数据库只有1个
- 次要文件 .ndf:主文件以外的所有信息, 可以有多个
- 事务日志 .ldf:恢复数据库的日志信息,每个数据库至少有1个
完整性约束
分类
- 类型约束
- 属性约束
- 关系变量约束
- 数据库约束
约束 | 含义 | 条件 |
---|---|---|
PRIMARY KEY | ||
UNIQUE | ||
NOT NULL | ||
CHECK | 约束属性范围 | |
FOREIGN KEY |
数据库安全
授权
授予权限
GRANT 权限 ON TABLE_NAME TO USERNAME [WITH GRANT OPTION]
1 |
|
表示将更新table表的age属性的权限授予kkyou用户, 并且kkyou用户可以将自己的权限授予他人
角色
创建角色
1 |
|
收回权限
1 |
|
数据库恢复
事务
定义
事务是用户定义的一个数据库操作序列,每个事务都是不可分割的整体
事务相关的命令
BEGIN TRANSACTION #开始事务
ROLLBACK #执行错误,回滚,撤销所有操作
COMMIT #执行成功,提交事务
END TRANSACTION #结束事务
事务的ACID特性
原子性Atomic: 事务操作要么全部执行,要么都不执行,不可分割
一致性Consistent: 事务单独运行时(没有并发运行的其它事务),应保证数据库的一致性
隔离性Isolation: 多事务并发执行,每个事务之间不可相互干扰
持续性Duration: 事务一旦提交,它对数据库的数据改变应该是永久的
数据库恢复
需要解决的问题
- 如何建立冗余数据
- 如何利用冗余数据恢复数据库
日志
定义
日志是DBMS用来记录事务对数据库进行更新操作的文件
描述内容
- 事务标识符:事务的唯一标识符
- 数据项标识符:事务操作对象的唯一标识符
- 前像(BI):更新前数据的旧值
- 后像(AI):更新后数据的新值
日志存储
先存入缓冲区,再存入稳定的储存器
记录形式
- \
事务T已经开始 - \
事务T成功提交 - \
事务T不能成功完成,已终止 - \
事务T对数据项X进行操作,前像为V1,后像为V2
先写日志规则
- 在主存中的数据块输出到数据库之前,所有与该数据库有关的日志记录必须已输出到稳定的储存器上(先更新日志,再更新数据库)
- 事务要进入提交状态,必须是事务的日志,包括COMMIT记录都写入稳定存储器
保持事务原子性的三种方案
后像(BI)在事务提交之后再写入数据库(恢复将数据更新为新值)
缺点:增加事务平均缓冲的次数
日志记录: \
, V为后像,不储存前像。
动作 | 日志 |
---|---|
READ(data1 | \ |
change data1 | |
WRITE(data1) | \ |
$\dots$ | |
\ |
|
将数据写入磁盘(数据库) |
恢复步骤(从前向后,改为最后的新值)
- 从后向前扫描日志文件,将COMMIT的事务放入redo-list中
- 从前向后扫描日志文件,对每个\
记录: - 若T不是redo-list中的事务,则什么都不做
- 若T是redo-list中的事务,则将新值V写入磁盘
- 对未完成的事务,在日志文件中写入\
记录并刷新日志
后像(AI)在事务提交前完全写入数据库(恢复将数据改回旧值)
缺点:增加磁盘I/O次数
日志记录: \
V为前像,不储存后像。 要保证系统故障后恢复,需满足:
- 记录数据变化的日志记录要在数据项写入磁盘前写入稳定的存储器
- COMMIT日志记录要在数据项写入磁盘后再写入稳定的存储器
动作 | 日志 |
---|---|
\ |
|
READ(data1) | |
change data1 | |
WRITE(data1) | \ |
$\dots$ | |
更新数据到磁盘 | |
\ |
**恢复步骤** (从后向前,改为最初的旧值)
- 对日志文件从后向前扫描,将
的事务放入redo-list中 - 对每一个
,若T不在redo-list中,则什么都不做 - 对每一个
,若T在redo-list中,则将X置为旧值V
后像(AI)在事务提交前后写入数据库
日志记录:\
恢复步骤(已提交记录设为新值,未提交记录回滚为旧值)
- 对日志文件从后向前扫描,对有COMMIT记录和没有的事务分别放两个队列:redo-list、undo-list
- 从前向后扫描日志文件,重新执行redo-list中的事务
- 从后向前扫描日志文件,撤销执行undo-list中的事务
创建检查点的方法
提交一致性检查点
- 新的事务不能开始直到检查点完成
- 现有的事务继续执行到提交或中止,并将相关日志都写入稳定存储器
- 将当前日志缓冲区中的日志写回稳定存储器中的日志文件
- 将日志记录\
写入存储器 检查点之前的事务都已经完成,因此无需恢复之前的数据。
恢复时,从后向前扫描日志,\
后的记录都要恢复
高速缓存一致性检查点
- 新的事务不能开始直到检查点完成
- 已存在的事务不允许进行更新操作
- 将当前日志缓冲区中的日志写回稳定存储器中的日志文件
- 将数据缓冲区的所有数据写入磁盘
- 将日志记录\
写入存储器,L是所有活动事务的列表 检查点前:事务已提交,不处理
检查点中:事务处于活动状态,若事务提交,执行REDO,否则执行UNDO
若后像在事务提交后才写入数据库,没有提交记录时,不必UNDO
若后像在事务提交前写入数据库,有提交记录,不必执行REDO
- 模糊一致性检查点
数据转储
备份级别
- 完全转储:备份整个数据库
- 增量备份:只备份上次备份后改变的数据
转储分类
- 静态转储:转储期间不允许有事务进行
- 动态转储:转储期间允许事务对数据库进行更新(需要用日志记录纠正数据库不一致状态)
故障类型
事务故障
- 逻辑错误(错误输入、找不到数据、溢出等)
系统错误(系统进入不良状态,如死锁)
恢复:使用之前的三种方案中的一种即可
系统故障:硬件、软件故障
恢复:使用之前的三种方案中的一种即可
介质故障:数据传输过程中发生的内容错误
恢复:完成转储备份工作
RAID(冗余磁盘阵列)
目的:应对介质故障带来的严重影响
优点
- 成本低、功耗小、传输效率高
- 可提供容错功能
- 具备数据校验功能
事务的并发控制
优点
- 改善系统资源利用
- 简短事务等待时间
调度:事务按时间排序的序列
串行调度:事务是一个个执行的(n个事务进行串行调度,有n!种方式)
交叉调度可能引起的问题
读脏数据
脏数据:未提交事务所写的数据(读了ROLLBACK之前的数据)
不可重复读(两次读到不同的数据)
丢失修改(两个事务同时修改数据,其中一个事务的修改丢失)
可串行化
若多个事务交叉调度和某一串行调度的结果相同时,该调度为可串行化的
冲突可串行化
多事务交叉调度发生冲突的条件
- 不同事务对同一数据操作
- 不同事务操作指令中含W操作
冲突可串行化判断方法:
交换调度S不冲突的指令,得到新的调度S’。S和S’是冲突等价的,若一个调度冲突等价于一个串行调度,则该调度室冲突可串行化的。
视图可串行化
对同一事务集,若事务在任何时候都读到相同的值,写入数据库的最终状态也是相同的,则称事务视图等价
可串行化判断
- 调度冲突等价于串行调度
- 前驱图(点为事务,产生冲突则连线,入度点为先执行的,若产生环,则不可串行调度)
可恢复条件
不读脏数据(Ti读了Tj修改的数据,则Tj事务先提交,Ti后提交)
基于锁的并发控制协议
加锁方式(S和X锁之间都是不相容的)
- 共享锁(S):可读数据,不可写(申请队列为空,数据项没有排它锁,则可授予)SLOCK(Q)
- 排他锁(X):可以读写数据(申请队列为空,数据项没有锁,则可授予)XLOCK(Q)
- ULOCK(Q):释放数据项Q的锁,事务提交或中止即可释放锁
两段锁协议(2PL)
保证冲突可串行化的充要条件,不能预防死锁
- 增长阶段:读写数据前,应首先获得数据的锁
- 收缩阶段:释放锁后,事务不再申请获得其他任何锁
活锁、死锁
活锁
其他事务一直抢先得到锁,使得一个事务一直得不到锁
死锁
事务互相等待,形成死锁
死锁的预防
顺序封锁法:事务对锁的申请按顺序进行
一次封锁法:事务执行前获得所有锁,若不能获得所需的所有锁,则事务中止
缺点:事务开始前很难知道所需的所有锁、一次性获得所有锁,但有的锁会在很久之后使用,降低系统并发度
用时间戳的死锁预防:早运行的事务优先级高
- Wait-die机制:申请锁时,若事务相较冲突的事务优先级高,则等待,否则中止
- Wound-wait机制:申请锁时,若事务相较冲突的事务优先级高,则中止正在使用锁的事务,否则事务等待
死锁的检测预防
等待图(点为事务,当事务A等待B释放锁时,边由A连向B)
死锁解除:撤销事务
需要解决的问题:
- 撤销事务的选择
- 撤销事务的程度(全部回滚|部分回滚)
数据库设计理论
设计的不好的数据库可能出现的问题:
- 数据冗余
- 操作异常
- 更新异常
- 删除异常
- 插入异常
模式分解是解决数据冗余的主要方法
数据依赖包括
- 函数依赖
- 多值依赖
- 连接依赖
函数依赖
关系模式R(U)中,$X\subseteq U, Y\subseteq U$,若t[X] = s[X],则有t[Y] = s[Y],则称属性或属性组Y函数依赖于X
FD X$\to$Y (X:决定因子、Y:依赖因子)
平凡函数依赖
若$X\subseteq Y, 则X\to Y$
完全函数依赖
部分函数依赖
传递函数依赖
$X \to Y, Y \nrightarrow X, Y\rightarrow Z,则 Z对X传递函数依赖$
$X \to Y, Y \nrightarrow X, Y\rightarrow Z \models X\rightarrow Z$
F的闭包:F和F所蕴含的依赖的全体
属性集的闭包
关系无损分解的判断方法
追逐法
若关系被分解为两个关系,则无损分解的充要条件是:
$(U_1\cap U_2)\rightarrow (U_1 - U_2)$或
$(U_1\cap U_2)\rightarrow (U_2-U_1)$
$X\to Y 在R上成立,且X\cap Y=\phi,则{R-Y, XY}是无损分解$
保持函数依赖的分解的判断方法
执行以下算法:
Z=X
while Z 改变 do{
for i=1 to k{
$Z = Z\cup ((Z \cap U_i)^+\cap U_i)$
}
}
若最终所有的Z包含正确的$Z^+$,则分解保持函数依赖
规范化
1NF
每个属性值都是原子值
2NF
每个非主属性都完全函数依赖于候选码
3NF
每个非主属性都不传递依赖于候选码,每个非主属性都完全函数依赖于候选码
$2NF\subset 3NF$
BCNF
$R\in$ 1NF,且每个属性都不传递依赖于R的候选码,则R是BCNF模式
数据库设计
数据库设计方法
- 直观设计法
- 规范化设计法
- 面向对象设计法
- 计算机辅助方法
数据库设计的基本过程
需求分析阶段
需求调研
需求分析
编写需求分析说明书
需求分析说明书验证
概念设计阶段
逻辑设计阶段
物理设计阶段
实现阶段
运行和维护阶段
ER图
全局视图集成的重要工作:
- 冲突消除
- 冗余消除与优化
局部模式间的冲突:
- 属性冲突
- 命名冲突
- 结构冲突
数据字典
- 数据项
- 数据结构
- 数据流
- 数据存储
- 数据处理
存取方法设计
- 聚簇
- 索引
- hash
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!