软件设计师-06,数据库技术基础
Joker2Yue数据库基础知识、规范化基础知识、新技术基础
DBS:Database System,数据库系统
1NF:First Normal Form,第一范式
2NF:Second Normal Form,第二范式
3NF:Third Normal Form,第三范式
BCNF:Boyce-Codd Normal Form,巴斯-科德范式
考纲
数据库基础知识
数据库基本概念
-
数据库系统DBS:是一个采用了数据库技术,有组织地、动态地存储大量相关数据,方便多用户访问的计算机系统。其由下面四个部分组成:
- 数据库(统一管理、长期存储在计算机内的,有组织的相关数据的集合)
- 硬件(构成计算机系统包活存储数据所需的外音设备)
- 软件(操作系统、数据库管理系统及应用程序)
- 人员(系统分析和数据库设计人员、应用程序员、最终用户、数据库管理员DBA)。
-
数据库管理系统DBMS的功能
- 实现对共享数据有效的组织、管理和存取。
- 包括数据定义、数据库操作、数据库运行管理、数据的存储管理、数据库的建立和维护等。
三级模式-两级映像
-
内模式:管理如何存储物理的数据,对应具体物理存储文件。
-
模式:又称为概念模式,就是我们通常使用的基本表,根据应用、需求将物理数据划分成一张张表。
-
外模式:对应数据库中的视图这个级别将表进行一定的处理后再提供给用户使用
-
外模式一模式映像:是表和视图之间的映射,存在于概念级和外部级之间,若表中数据发生了修改,只需要修改此映射,而无需修改应用程序。
-
模式一内模式映像:是表和数据的物理存储之间的映射,存在于概念级和内部级之间,若修改了数据存储方式,只需要修改此映射,而不需要去修改应用程序。
数据库设计
-
需求分析:即分析数据存储的要求,产出物有数据流图、数据字典、需求说明书。
-
概念结构设计:就是设计E-R图,也即实体属性图,与物理实现无关,说明有哪些实体实体有哪些属性。
-
逻辑结构设计:将E-R图,转换成关系模式也即转换成实际的表和表中的列属性,这里要考虑很多规范化的东西
-
物理设计:根据生成的表等概念,生成物理数据库。
E-R模型
-
数据模型三要素:数据结构(所研究的对象类型的集合)、数据操作(对数据库中各种对象的实例允许执行的操作的集合)、数据的约束条件(一组完整性规则的集合)。
-
E-R模型:即实体-联系模型,使用椭圆表示属性(一般没有)、长方形表示实体、菱形表示联系,联系两端要标注联系类型。
-
联系类型:一对一1:1、一对多1:N、多对多M:N(有的也写
*
)。 -
属性分类:简单属性和复合属性(属性是否可以分割)、单值属性和多值属性(属性有多个取值)、NULL属性(无意义)、派生属性(可由其他属性生成)。
关系模型
-
关系模型也就是数据库中常用的表,包括实体的属性,标识出实体的主键和外键,如下:
模型转换
-
E-R图转换为关系模型每个实体都对应一个关系模式:联系分为三种:
- 1:1联系中,联系可以放到任意的两端实体中,作为一个属性(要保证1:1的两端关联):
- 1:N的联系中,联系可以单独作为一个关系模式,也可以在N端中加入1端实体的主键:
- M:N的联系中,联系必须作为一个单独的关系模式,其主键是M和N端的联合主键
关系代数运算
-
并:结果是两张表中所有记录数合并,相同记录只显示一次。
-
交:结果是两张表中租同的记录
-
差:S1-S2,结果是S1表中有而S2表中没有的那些记录
-
笛卡尔积:
S1*S2
,产生的结果包括S1和S2的所有属性列,并且S1中每条记录依次和S2中所有记录组合成一条记录,最终属性列为S1+S2
属性列,记录数为S1*S2
记录数。- 下图中,应当写为
S1.Sno,S1.Sname,S1.Sdept,S2.Sno,S2.sname,S2.Sdept
- 下图中,应当写为
-
投影:实际是按条件选择某关系模式中的某列,列也可以用数字表示。(π)
-
选择:实际是按条件选择某关系模式中的某条记录。(ϭ)
-
自然连接:自然连接的结果显示全部的属性列,但是相同属性列只显示一次,显示两个关系模式中属性相同值相同的记录(⋈)(显示列名相同且值相同的记录)
-
设有关系R、S如下左图所示,自然连接结果如下右图所示
-
上图中,左侧
A,C
列有值a,c
,右侧A,C
列也有值a,c
,则将这一列全部统计到最右边同样的,左侧
A,C
列有值b,d
,右侧A,C
也有值b,d
,将其统计到最右边
-
规范化基础知识
函数依赖
-
函数依赖:如果给定一个X,能够唯一确定一个Y,我们称X确定Y,或者说Y依赖于X。例如,如果有一个函数
Y = f(X)
,那么我们可以表示为X → Y
。 -
函数依赖文可扩展以下两种规则:
- 部分函数依赖:当我们有一个函数依赖
A → C
,但同时(A, B)
也可以确定C
时,我们称其为部分函数依赖。这意味着在组合(A, B)
中,只有一部分(即A
)可以确定C
。 - 传递函数依赖:如果存在函数依赖关系
A → B
和B → C
,并且A
和B
不等价,那么我们可以推导出A → C
,这就是传递函数依赖。如果A
和B
是等价的,那么直接可以确定C
,不需要传递。
- 部分函数依赖:当我们有一个函数依赖
键与约束
-
键的基本概念
-
超键:能推出所有属性的属性组的集合
-
候选键:是能够推出所有属性组的最小集合,是极小的超键集,是超键的子集
- 一定属于候选键的属性:只出现在左边,或者左右都没出现
- 可能属于候选键的属性:左右都出现
- 一定不是候选键的属性:只出现在右边
-
主键:任选一个候选键,即可作为主键。
-
外键:其他表中的主键。
-
主属性:包含在任何一个候选键内的属性都是主属性
-
非主属性:不包含在任何一个候选键内的属性
-
-
约束的基本概念
- 实体完整性约束:即主键约束,主键值不能为空,也不能重复。
- 参照完整性约束:即外键约束,外键必须是其他表中已经存在的主键的值,或者为空。
- 用户自定义完整性约束:自定义表达式约束,如设定年龄属性的值必须在0到150之间。
范式
-
第一范式(1NF - First Normal Form):
- 范式要求关系模式中的每个属性必须是原子性的,不可再分。这意味着属性的值不应该是包含其他值的集合或数组。
- 举例:在一个学生选课表中,学生姓名和选课课程号应该分别作为一个属性,而不是将它们合并成一个属性。
-
第二范式(2NF - Second Normal Form):
-
在第一范式的基础上,要求关系模式中的非主属性完全依赖于候选键,即不存在部分依赖。
-
举例:
- 考虑一个订单表,其中包含“订单号”和“产品编号”作为候选键,还有“产品名称”、“购买数量”和“产品价格”等作为属性。如果“产品名称”和“产品价格”依赖于“产品编号”,而不是依赖于整个“订单号”,那么这将违反第二范式。
- 解决方法是将产品信息存储在一个独立的表中,并使用“产品编号”作为主键。
-
更加详细的举例:
-
假设我们有一个存储订单信息的表格,其结构如下:
订单表(Orders)
在这个表中,订单号(OrderID)是主键。然而,我们可以看到产品名称、产品描述、产品价格等不依赖于所有的候选键(订单号和产品编号),而只依赖于部分的候选键(产品编号)。
-
为了符合第二范式,我们可以进行表的分解,将产品信息从订单表中抽取出来,创建一个独立的产品表。修正后的结构如下:
订单表(Orders)
产品表(Products)
-
现在,订单表中的每个记录只包含订单号、产品编号和数量,而产品信息存储在独立的产品表中。这种设计满足了第二范式的要求,因为非主属性(产品名称、产品描述、产品价格)现在完全依赖于候选键(产品编号),没有部分依赖的情况存在。这种分解可以减少数据冗余,提高数据的一致性和规范性。
-
在这个例子中,我们解决的是部分函数依赖的问题
(订单号,产品编号)→产品名称
。也就是说,表中的非主属性依赖于候选键的某一部分,而不是所有的候选键。我们通过分解表来确保每个非主属性直接依赖于整个候选键,从而符合2NF。
-
-
-
第三范式(3NF - Third Normal Form):
-
在第一、第二范式的基础上,要求关系模式中的每个非主属性不应该对其他非主属性产生传递依赖。
-
举例:
-
考虑一个员工信息表,其中包含员工ID(主键)、员工姓名、部门、部门地点。按照实际情况,部门地点应该依赖于部门,而不是应该直接依赖于员工ID(尽管它是主键),这不符合第三范式。
-
为符合3NF与实际情况,我们需要将部门地点信息从员工表中抽取出来创建一个独立的部门表,确保每个非主属性都直接依赖于主键。
-
-
更加详细的举例:
-
让我们考虑一个不符合第三范式(3NF)的表,并尝试解决这个问题。
假设我们有一个存储员工信息的表格,其结构如下:
员工表(Employees)
在这个表中,员工ID是主键。然而,我们可以看到部门地点(DepartmentLocation)并不直接依赖于员工ID,而是依赖于部门(Department)。因此,存在传递函数依赖的情况。
-
为了符合第三范式,我们可以进行表的分解,将部门信息从员工表中抽取出来,创建一个独立的部门表。修正后的结构如下:
员工表(Employees)
部门表(Departments)
-
现在,员工表中的每个记录只包含员工ID、姓名和部门ID,而部门地点信息存储在独立的部门表中。这种设计满足了第三范式的要求,因为非主属性(部门地点)不再传递依赖于候选键(员工ID),也没有部分依赖的情况存在。这种分解有助于减少数据冗余,提高数据的一致性和规范性。
-
在这个例子中,我们解决的是传递函数依赖(
员工ID→部门→工作地点
)的问题。也就是说,非主属性依赖于其他非主属性(部门地点→部门
),而不仅仅依赖于候选键(员工ID
)。我们通过分解表来确保非主属性不会传递依赖于其他非主属性,从而符合3NF。
-
-
-
巴斯-科德范式(BCNF - Boyce-Codd Normal Form):
-
在第三范式的基础上,如果任何属性对任一候选关键字都不存在传递依赖,则符合BC范式。
它要求关系模式中的每个非主属性必须完全依赖于候选键。
通俗的说,BCNF所有依赖关系的左侧必须为候选键,而其余要求均与3NF一致。
-
-
实践
-
图示:有关系模式
R(S,T,J)
,依赖集为F={SJ->T, T->J}
。画图可以求出其候选键为(S,T)
,(S,J)
。其中,
S
入度为0,但是从S
出发并不能直接遍历整个图,从SJ→T
得出,(S,J)
才能得出T
,则(S,J)
是一个候选键。T→J
中T
的入度不为0,于是将S
与T
一起作为一个候选码,即(S,T)
-
那么上述关系符合第几范式呢?
第一范式:符合,属性都无法再分割
第二范式:符合。这里
(S,T)→J
中有T→J
,此处虽然为传递函数依赖,但是第二范式的规定是:非主属性必须完全依赖于候选键,而此处S,J,T
均为主属性,也就没有要求说要完全依赖于候选键了。第三范式:符合。这里都没有非主属性了,也就没有要求了。
BC范式:不符合,因为
T→J
,而T
不是一个超键(或者这样说:因为SJ→T→J
,则SJ
传递依赖于J
,不符合BCNF中“任何属性对任一候选关键字都不存在传递依赖”)
-
-
例题1:
-
这道题中,我们可以采用画图的方式来找出候选键。按照图,如果一个属性只在左边出现,那么它一定是候选键的属性之一(入度为0)。信息中
F={AB→C,CD→B}
,其中C,B
都在右边出现过,那么A,D
肯定是候选键的属性之一,每个候选键都应该包含A,D
。然后通过入度为零的节点来尝试推导整个树,
A,D
并不能单独地遍历,题目中只有AB→C
,则ABD
肯定是一个候选键;又CD→B
,则ACD
也是一个候选键。主属性呢?只要在候选键中的属性都是主属性,则
A,B,C,D
都是主属性
-
-
例题2:
-
这道题中,我们划掉在右边出现过的属性:
E
,N,M
,L,Q。再看F={E→N,EM→Q,M→L}
,可以得出(E,M)
为主属性,(N,Q,L)
为非主属性。 -
符合第几范式呢?
第一范式:符合,属性都无法再分割
第二范式:不符合。因为
EM→Q
,而E→N
,M→L
,说明它们之间存在部分函数依赖。如果不存在,就必须要(E,M)
才能决定其他非主属性,而现在只需要其中一个就行。
-
-
模式分解
-
范式之间的转换一般都是通过拆分属性,即模式分解,将具有部分函数依赖和传递依赖的属性分离出来,来达到一步步优化,一般分为以下两种,
-
保持函数依赖分解:
- 对于关系模式
R
,有依赖集F
,若对R
进行分解,分解出来的多个关系模式,保持原来的依赖集不变,则为保持函数依赖的分解。另外,注意要消除掉冗余依赖(如传递依赖)。 - 保持函数依赖分解后的关系模式,能够还原原有的、去掉冗余依赖的依赖集。
- 实例:设原关系模式
R(A,B,C)
,依赖集F(A->B,B->C,A->C)
,将其分解为两个关系模式R1(A,B)
和R2(B,C)
,此时R1
中保持依赖A->B
,R2
保持依赖B->C
,说明分解后的R1
和R2
是保持函数依赖的分解,因为A->C
这个函数依赖实际是一个冗余依赖,可以由前两个依赖传递得到,因此不需要保留。
- 对于关系模式
-
无损分解:
-
分解后的关系模式能够还原出原关系模式,就是无损分解,不能还原就是有损。
-
无损分解后的关系模式,能够还原原有的关系模式
-
可以通过表格法求解,如下:
-
当分解为两个关系模式的时候,除了表格法之外,也可以通过以下定理来判断是否无损分解
定理:如果
R
的分解为p={R1,R2}
,F
为R
所满足的函数依赖集合,分解p
具有无损连接性的充分必要条件是R1∩R2→(R1-R2)
或者R1∩R2→(R2-R1)
。
-
-
-
例题
事务管理
-
事务提交commit,事务回滚rollback
-
在数据库管理中,事务是由一系列操作组成的单元,这些操作要么全部执行,要么全部不执行。事务具有四种主要特性:
- (操作)原子性:事务具有原子性,这意味着事务中的操作要么全部执行成功,要么全部失败回滚,不存在部分执行的情况。这确保了数据的完整性。
- (数据)一致性:一致性要求在事务执行之后,数据库状态必须保持一致。例如,在银行转账中,不会出现从一个账户扣款成功而另一个账户未收到款项的情况。
- (执行)隔离性:隔离性确保每个事务的操作在提交之前对其他事务是不可见的。不同事务之间相互隔离,互不干扰。这可以防止并发执行时的数据冲突和竞争条件。
- (改变)持久性:持久性确保一旦事务成功提交,其结果将永久保存在数据库中,即使系统发生故障或崩溃,也不会丢失已提交的事务操作结果。
并发控制
-
事务是并发控制的前提条件,而并发控制旨在管理不同事务的并发执行以提高系统效率。然而,并发控制面临以下三个主要问题:
-
丢失更新:当多个事务同时对同一数据进行修改并写回时,后一个事务的写回操作会覆盖前一个事务的写回结果,导致前一个事务的更新丢失。这意味着对数据的一次更新会被覆盖,造成数据不一致。
-
不可重复读:在一个事务中,如果一个数据被多次读取,而期间另一个事务修改了该数据并提交,那么在后续的读取操作中,事务会发现数据不一致,因为数据已经发生了变化。这种情况下,一个事务多次读取同一数据会导致数据不一致。
-
读脏数据:事务1对数据A进行了修改后,事务2读数据A,而后事务1回滚,数据A恢复了原来的值,那么事务2对数据A做的事是无效的,读到了脏数据。
-
三级封锁协议
-
在数据库管理中,三级封锁协议是一种用于管理并发访问数据的规则。它包括以下两种类型的锁:
- X锁(排它锁):当事务T对数据对象A加上X锁时,只允许事务T读取和修改A。其他事务无法再对A加任何类型的锁,直到事务T释放A上的锁。
- S锁(共享锁):当事务T对数据对象A加上S锁时,只允许事务T读取A,但不能修改A。其他事务只能再对A加S锁(不能加X锁),直到事务T释放A上的S锁。
-
三级封锁协议分为以下三个级别:
- 一级封锁协议:根据这一级别,事务在修改数据R之前必须先对其加X锁,并且保持锁直到事务结束才释放。这可以解决丢失更新问题。
- 二级封锁协议:在一级封锁协议的基础上,事务在读取数据R之前必须先对其加S锁,读取完毕后即可释放S锁。这不仅可以解决丢失更新问题,还可以防止读脏数据问题。
- 三级封锁协议:三级封锁协议结合了一级和二级封锁协议的特性。事务T在读取数据R之前先对其加S锁,然后在修改数据之前再加X锁,直到事务结束才释放。这可以解决丢失更新、读脏数据和数据重复读等多种并发问题。
新技术基础
数据库安全
-
数据库系统产生的故障如下图所示
-
数据库备份
-
静态转储:即冷备份,指在转储期间不允许对数据库进行任何存取、修改操作;
- 优点是非常快速的备份方法、容易归档(直接物理复制操作);
- 缺点是只能提供到某一时间点上的恢复,不能做其他工作,不能按表或按用户恢复。
-
动态转储:即热备份,在转储期间充许对数据库进行存取、修改操作,因此,转储和用户事务可并发执行;
- 优点是可在表空间或数据库文件级备份,数据库扔可使用,可达到秒级恢复;
- 缺点是不能出错,否则后果严重,若热备份不成功,所得结果几乎全部无效。
-
完全备份:备份所有数据。
差量备份:仅备份上一次完全备份之后变化的数据。
增量备份:备份上一次备份之后变化的数据。
日志文件:在事务处理过程中,DBMS把事务开始、事务结束以及对数据库的插入、删除和修改的每一次操作写入日志文件。一旦发生故障,DBMS的恢复子系统利用日志文件撤销事务对数据库的改变,回退到事务的初始状态。
-
分布式数据库
局部数据库位于不同的物理位置,使用一个全局DBMS将所有局部数据库联网管理,这就是分布式数据库。其体系结构如下图所示:
-
分片模式
- 水平分片:将表中水平的记录分别存放在不同的地方。(行)
- 垂直分片:将表中的垂直的列值分别存放在不同的地方。(列)
-
分布透明性
- 分片透明性:用户或应用程序不需要知道逻辑上访问的表具体是如何分块存储的。
- 位置透明性:应用程序不关心数据存储物理位置的改变。
- 逻辑透明性:用户或应用程序无需知道局部使用的是哪种数据模型
- 复制透明性:用户或应用程序不关心复制的数据从何而来。
数据仓库
-
数据仓库是一种特殊类型的数据库。与传统数据库不同,数据库中的数据会随着时间的推移不断积累,这可能会降低系统运行效率。对于某些应用程序而言,较早之前的数据可能不再必要。为了提高系统效率并减少数据丢失的风险,我们通常会将这些历史数据从主数据库中提取出来,保存到一个单独的数据库中,这就是数据仓库。
-
数据仓库与常规数据库不同,它的设计目的不是为了应用,是面向主题的,用于数据分析和集成不同数据表。数据仓库通常保持相对稳定,很少进行数据修改,而是定期在特定时间点进行大批量数据插入,以反映历史数据的变化。
-
总结来看,数据仓库的形成过程可以概括如下图所示:
数据挖掘
从上述可以明显看出,建立数据仓库后,它具备了两项关键作用。首先,数据仓库用于执行数据的高级查询、分析,以及生成各种报表。其次,数据仓库为数据挖掘工具提供了宝贵的历史数据,使其能够深入挖掘数据之间的关联关系,发现潜在的价值。
数据挖掘可通过不同的分析方法来实现:
-
关联分析:主要用于发现不同事件之间的关联性,即一个事件发生的同时,另一个事件也经常会发生。
-
序列分析:该方法用于寻找一定时间内连续发生的事件,这些事件形成了一个特定的序列。这些发现的序列通常具有普遍的意义。
-
分类分析:分类分析依据样本的特征和属性,为样本分配适当的类别。在进行分类分析时,首先为每个记录分配一个标签(表示不同的类别或特征),然后分析这些标记化的记录,以描述它们的特征和属性。
-
聚类分析:聚类分析的目标是根据“相似性原则”,将原本没有类别的样本划分为不同的组,并对每个组进行详细描述。
商业智能
商业智能(BI)系统通常包括四个关键阶段:数据预处理、数据仓库建设、数据分析和数据可视化。
-
数据预处理:这是整合企业原始数据的首要步骤,通常包括数据的抽取(Extraction)、转换(Transformation)和加载(Load)三个过程,通常被缩写为ETL过程。
-
数据仓库建设:建立数据仓库是处理大量数据的基础,它提供了一个结构化的环境,用于存储和管理企业数据。
-
数据分析:数据分析是展现系统智能的核心部分。通常采用联机分析处理(OLAP)和数据挖掘等技术。OLAP不仅可以进行数据的汇总和聚合,还提供了诸如切片、切块、下钻、上卷和旋转等多维数据分析功能,使用户能够轻松进行多层次的数据分析。而数据挖掘旨在发现数据背后的潜在知识,通过关联分析、聚类和分类等方法构建分析模型,以预测企业未来的发展趋势和可能面临的问题。
-
数据可视化:随着数据量和分析技术的增加,数据可视化变得愈发重要。数据可视化有助于以图形和图表的方式呈现系统分析结果,使用户能够更轻松地理解和利用海量数据。
这些阶段协同工作,以支持企业更好地理解其数据、做出决策并获得有价值的洞察。
反规范化技术
如前所述,规范化操作有助于避免插入、更新和删除异常,通常通过模式分解将表分拆以实现这一目标。
然而,表的分拆会在查询方面产生不利影响。每次查询可能需要关联多个表,从而显著降低了查询效率。因此,有时候需要采用反规范化技术来提高查询性能。
反规范化技术的方法包括增加派生列、添加冗余列、重新组织表和拆分表等。这些方法主要旨在增加冗余信息,以提高查询效率,可视为规范化操作的逆过程。
大数据
-
特点:大量化、多样化、价值密度低、快速化。大数据和传统数据的比较如下:
-
要处理大数据,一般使用集成平台,称为大数据处理系统,其特征为:
- 高度可扩展性、高性能、高度容错、支持异构环境、较短的分析延迟、易用且开放的接口、较低成本、向下兼容性。
SQL语言
-
常见的语句
操作 SQL语法 说明 创建表 CREATE TABLE 创建数据库表 指定主键 PRIMARY KEY() 定义主键约束 指定外键 FOREIGN KEY() 定义外键约束 修改表 ALTER TABLE 修改数据库表结构 删除表 DROP TABLE 删除数据库表 创建索引 CREATE INDEX 创建索引以提高查询性能 创建视图 CREATE VIEW 创建虚拟表,简化数据访问和操作 数据库查询 SELECT … FROM … WHERE 从数据库中查询数据 分组查询 SELECT sno, AVG(score) FROM student GROUP BY sno HAVING (AVG(score) > 60) 对数据进行分组并应用条件 更名运算 SELECT sno AS “学号” FROM t 为查询结果中的列起别名 字符串匹配 SELECT * FROM t1 WHERE sname LIKE ‘a_’ 使用LIKE进行字符串匹配 数据库插入 INSERT INTO t1 VALUES (‘a’, 66) 向表中插入数据 数据库删除 DELETE FROM t1 WHERE sno = 4 从表中删除数据 数据库修改 UPDATE t1 SET sname = ‘aa’ WHERE sno = 3 修改表中的数据 排序 SELECT * FROM t1 ORDER BY sno DESC 对查询结果进行排序,默认为升序 DISTINCT SELECT DISTINCT column_name FROM table_name 过滤重复的选项,返回不重复的记录 UNION SELECT column1 FROM table1 UNION SELECT column2 FROM table2 将两个查询的结果合并为一个结果集,去重 INTERSECT SELECT column1 FROM table1 INTERSECT SELECT column2 FROM table2 返回两个查询的交集 MIN SELECT MIN(column_name) FROM table_name 返回列中的最小值 AVG SELECT AVG(column_name) FROM table_name 返回列中的平均值 MAX SELECT MAX(column_name) FROM table_name 返回列中的最大值 -
例题