数据库
数据库
概念
数据:数据是数据库中存储的基本对象,是描述事物的符号记录。
数据的种类:文本、图形、图像、音频、视频
数据库:是长期存储在计算机内、有组织的、可共享的大量数据的集合。
数据库的基本特征:
- 数据是按一定数据模型组织、描述、和存储;
- 可为各种用户共享;
- 冗余度较小;
- 数据独立性较高;
- 易扩展;
数据库系统:
数据库管理系统:
三级模式-两级映射
三级模式
内模式
管理如何存储物理的数据,对应具体物理存储文件。
概念模式
简称模式,是数据库中的基本表。根据应用、需求将物理数据划分成一张张表。
外模式
对应数据库中的视图这个级别,将表进行一定的处理后再提供给用户使用。
两级映射
外模式-模式映像
表和视图之间的映射,存在于概念级和外部级之间,若表中数据发生了修改,只需要修改此映射,而无需修改应用程序。
模式-内模式映像
是表和数据的物理存储之间的映射,存在于概念级和内部级之间,所修改了数据存储方式,只需要修改此映射,而不需要去修改应用程序。
数据库设计
需求分析
即分析数据存储的要求,产出物有数据流图、数据字典、需求说明书。获得用户对系统的三个要求:信息要求、处理要求、系统要求。
概念结构设计
这个阶段是设计 E-R 图,即实体-联系图。工作步骤包括:选择局部应用、逐一设计分 E-R 图、E-R图合并。
分 E-R 图进行合并时,他们之间存在的冲突主要有以下三类:
- 属性冲突。同一属性可能会存在于不同的分 E-R 图中。
- 命名冲突。相同意义的属性,在不同的分 E-R 图上有着不同的命名,或者是名称相同的属性在不同的分 E-R 图中代表着不同的意义。
- 结构冲突。同一实体在不同的分 E-R 图中有着不同的属性,同一对象在某一分 E-R 图中被抽象为实体,而在另一分 E-R 图中又被抽象为属性。
逻辑结构设计
将 E-R 图转换成关系模式。工作步骤包括:确定数据模型、将 E-R 图转换成指定的数据模型、确定完整性约束和确定用户视图。
物理设计
确定数据分布、存储结构和访问方式。
数据库实施阶段
根据逻辑设计和物理设计阶段的结果建立数据库、编制与调式应用程序,组织数据入库,并进行试运行。
数据库运行和维护阶段
数据库应用系统经过试运行即可投入运行,但该阶段需要不断地对系统进行评价、调整与修改。
数据模型
四种数据模型
关系模型
关系模型师二维表的形式表示的实体-联系模型,是将实体-联系模型转换而来的,经开发人员设计的。
概念模型
概念模型是从用户的角度进行建模的,是现实世界到信息世界的第一抽象,是真正的实体-联系模型。
网状模型
网状模型是表示实体类型及其实体之间的联系,一个事物和另外几个都有联系形成一张网。
面向对象模型
面向对象模型是采用面向对象的方法设计数据库,以对象为单位,每个对象包括属性和方法,具有类和继承等特点。
数据模型三要素
- 数据结构。所研究的对象类型的集合;
- 数据操作。对数据库中的各种对象的实例允许执行的操作集合(一般是增删改查)。
- 数据的约束条件。一组完整性规则的集合。
E-R 图
用 E-R 图来描述概念数据模型,世界是由一组称作实体的基本对象和这些对象之间的联系构成的。
在 E-R 模型中,使用椭圆表示属性(一般没有)、长方形表示实体、菱形表示联系、联系的两端要填写联系类型。
E-R 模型转换为关系模型
每个实体都对应一个关系模式
一对一联系中,联系可以放在任意的两端实体中,作为一个属性,页可以转换为一个单独的关系模式;
一对N的联系中,联系可以单据作为一个关系模式,也可以在N端中键入一端实体的主键;
M对N的联系中,联系必须作为一个单独的关系模式,其主键是M和N端的联合主键;
关系代数
并集 S1 ∪ S2
结果是两张表中所有记录数的合并,相同记录只显示一次。
交集 S1 ∩ S2
结果是两张表中相同的记录。
差集 S1 - S2
结果是 S1 表中有但是 S2 表中没有的记录。
笛卡尔积 S1 × S2
产生的结果包括 S1 和 S2 的所有属性列,并且 S1 中每条记录一次和 S2 中所有记录组合成一条记录,最终属性列为 S1+S2 属性列,记录数为 S1 * S2 记录数。重复的列会显示。
投影 π
按条件选择某关系模式中的某列,列也可以用数字表示。
选择 σ
按条件选择某关系模式中的某条记录。
自然连接 S1 ⋈ S2
自然连接的结果是显示全部的属性列,但是相同的属性列只显示一次,显示两个关系模式中属性相同且值相同的记录。
如下有关系S1
A | B | C |
---|---|---|
a | b | c |
b | a | d |
c | d | e |
d | f | g |
关系S2
A | C | D |
---|---|---|
a | c | d |
d | f | g |
b | d | g |
S1 和 S2 自然连接的结果如下:
因为 S1 和 S2由两个相同的列 A 和 C,那么去掉重复的列之后,剩下的是 A B C D,那么寻找两个关系中 A 列和 C 列中值相同的行数记录下来
A | B | C | D |
---|---|---|---|
a | b | c | d |
b | a | d | g |
函数依赖
给定一个 x
,能唯一确定一个 y
,就称 x
确定 y
,或者说 y 依赖于 x,例如 函数。
函数依赖又可以扩展一下两种原则:
部分函数依赖:A 可以确定 C,(A,B)也可以确定 C,因为(A,B)中的一部分 A 可以确定 C,所以称为部分函数依赖。
传递函数依赖:当 A 和 B 不等价时,A 可确定 B,B 可确定 C,则 A 可确定 C,是传递函数依赖;若 A 和 B 等价,则不存在传递,直接就可以确定 C。
键与约束
给定一张用户表,有如下字段:
字段名 | 说明 | 示例 |
---|---|---|
user_id | 用户唯一 ID | 1001 |
user_name | 用户名 | 张三 |
id_card | 身份证号 | 330105202002025256 |
contact_information | 联系方式 | 杭州市上城区 XXX 号 |
company_id | 公司ID | 2001 |
超建:能唯一标识此表的属性集合,只要能标识唯一就行,比如
user_id+user_name
,id_card+user_name
都可以作为超键。候选键:超建中去掉冗余的属性,剩余的属性就是候选键。比如 user_id 和 id_card 都是候选键。
主键:任选一个候选键,即可作为主键。user_id 和 id_card 任意选一个作为主键。
外键:其它表中的主键。company_id 是一个外键;
主属性:候选键内的属性作为主属性,其它属性作为非主属性。
实体完整性约束:即主键约束,主键值不能为空,也不能重复。
参照完整性约束:即外键约束,外键必须是其他表中已经存在的主键的值,或者为空。
用户自定义完整性约束:自定义表达式约束,如设定年龄属性的值必须在0到150之间。
范式
第一范式 1NF
关系中的每一个分量必须是一个不可分的数据项。
第二范式 2NF(消除部分函数依赖)
如果关系 R 属于 1NF,且每一个非主属性完全函数依赖属于任何一个候选码,则 R 属于 2NF。
换句话说,2NF 就是在 1NF 的基础上,表中的每一个非主属性不会依赖于符合主键中的某一个列。
举例,存在如下一张学生表,有以下字段:
字段名 | 说明 | 示例 |
---|---|---|
student_no | 学号 | 20230101 |
student_name | 学生姓名 | 张三 |
department | 系编号 | 01 |
department_name | 系名称 | 数学系 |
department_director | 系主任姓名 | 张主任 |
course | 课程 | 数学分析 |
score | 课程分数 | 99 |
一个学号是一个学生;一个学号只能在一个系、一个学号可以选多个课程。
可以将学生表分解为如下:
学生表(学号、学生姓名、系编号、系名、系主任)
选课表(学号、课程号、成绩)
第三范式(消除传递依赖)
在满足 1NF 的基础上,表中不存在非主属性对键的传递依赖。
可以将学生表分解为如下:
学生表(学号、学生姓名、系编号)
系表(系编号、系名、系主任)
选课表(学号、课程号、成绩)
BC 范式
在第三范式的基础上进一步消除主属性对于码的部分函数依赖和传递依赖。就是说在某一种情况下,每一个依赖的左边决定因素都必然包含候选键。
模式分解
范式之间的转换一般是通过拆分属性,即模式分解,将具有部分函数依赖和传递依赖的属性分离开,来达到优化的目的。
保持函数依赖分解
如存在关系模式 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,而 A->C实际是一个冗余依赖,因为可以通过前两个依赖推倒出来,所以说明 R1 和 R2 保持函数依赖的分解。(注意,这个方法只能说明保持函数依赖,如果不满足这个条件,并不能说明不保持函数依赖,这是个充分条件而不是个必要条件)。
示例:有关系模式 R<U, F>,U={A, B, C, D, E},F={B -> A, D -> A, A -> E, AC -> B},则 R 的候选关键字为 CD
思路如下:
- 列举出所有的属性 A B C D E;
- 将依赖中的右边全部划掉
ABC DE,剩下 C 和 D; - 然后根据依赖关系,看看能否根据 C 和 D 推出 ABE:
- A 可以根据 D 推出;
- B 需要根据 AC 推出,而 D 可以推出 A,搜易 CD 可以推出 B;
- E 可以根据 A 退出来,所以 D 可以推出 E;
- 所以 CD 可以推出 ABE;
无损分解
分解后的关系模式能够还原出原关系模式,就是无损分解,不能还原就是有损。
当分解为两个关系模式时,可以通过一下定理判断是否无损分解:
定理:如果 R 的分解是 p={R1, R2},F 为 R 所满足的函数依赖集合,分解 p 具有无损连接性的充分必要条件是 R1 ∩ R2 -> R1 - R2
或者 R2 ∩ R1 -> R2 - R1
。
当分解为三个及以上关系模式时,可以通过表格发求解,如下:
由关系模式 成绩(学号,姓名,课程号,课程名,分数)
函数依赖为 F(学号 -> 姓名,课程号 -> 课程名,(学号,课程名)-> 分数),如果将其分解为:
- 成绩(学号,课程号,分数)
- 学生(学号,姓名)
- 课程(课程号,课程名)
可以通过表格发判断是否为无损分解。
初始表格如下:
学号 | 姓名 | 课程号 | 课程名 | 分数 | |
---|---|---|---|---|---|
成绩 | √ | √ | √ | ||
学生 | √ | √ | |||
课程 | √ | √ |
根据函数依赖,可以
- 从学号推出姓名,那么可以将成绩这一行中的姓名打勾;
- 从课程号推出课程名,那么可以将成绩这一行中的课程名打勾;
那么修正后的表格如下所示:
学号 | 姓名 | 课程号 | 课程名 | 分数 | |
---|---|---|---|---|---|
成绩 | √ | √ | √ | √ | √ |
学生 | √ | √ | |||
课程 | √ | √ |
可以看到其中成绩一行所有的列都是勾选的,所以该分解满足无损分解。
并发控制
事务四大特性,原子性、一致性、隔离性、持续性
事务间的影响
丢失更新:当前事务修改的数据被另一个事务修改了。
不可重复度:读两次数据的结果不一致,是因为另一个事物修改了这个数据。
脏读:当前事务读读到了另一个事务未提交的数据。
幻读:两次查询到的数据行数不一致,因为两次查询之间被别的事务插入了数据。
封锁协议
排它锁 X(写锁)
当前事务给数据加了排它锁之后,其它事务不能对该数据进行任何操作,只允许当前事务对该数据进行操作。
共享锁 S(读锁)
当前事务给数据加了共享锁之后,其它事务不能对该数据进行更新操作,但是其他事务页可以给该数据加上共享锁读取该数据。
三级封锁协议
一级:事务在修改数据之前必须对其加上写锁,写完数据之后释放写锁。可以解决丢失更新的问题。
二级:在读取数据之前必须对其加读锁,读完后释放读锁。可以解决丢失更新、读脏数据的问题。
三级:在读取数据之前必须对其加读锁,直到事务解释之后释放读锁。可以解决丢失更新、读脏数据、和不可重复度的问题。
数据库安全
备份
静态备份
冷备份。在转储期间不允许对数据库进行任何操作。
优点:备份快速,容易归档。
缺点:只能提供备份某一时间点上的回复,不能做其他工作,不能按表或者用户恢复。
动态转储
热备份。在转储期间允许对数据库进行操作,转储和用户事务可以并发执行。
优点:可在表空间或数据库文件级备份,数据库仍可使用,可达到秒级恢复。
缺点:备份不能出错,若热备份不成功,所得结果几乎全部无效。
完全备份
备份所有数据
差量备份
仅备份上一次完全备份之后变化的数据。
增量备份
备份上一次备份之后变化的数据。
分布式数据库
局部数据库位于不同的物理位置,使用一个全局数据库管理系统将所有局部数据库联网管理。
分片模式
水平分片:将表中的数据分别存放在不同的地方。
垂直分片:将表中的垂直的列值分别存放在不同的地方。
分布透明性
分片透明性:用户或应用程序不需要知道逻辑上访问的表具体是如何分块存储的。
位置透明性:应用程序不关心数据存储物理位置的改变。
逻辑透明性:用户或应用程序无需知道局部使用的是哪种数据模型。
复制透明性:用户或应用程序不关系复制的数据从何而来。
数据仓库
数据仓库是一个面向主题的、集成的、非易失的、随时间变化的数据集合,用于支持管理决策。
数据仓库的结构通常包含四个层次:
- 数据源:是数据仓库系统的基础,是整个系统的数据来源。
- 数据的存储与管理:是整个数据仓库系统的核心。
- OLAP(联机分析处理):对分析需要的数据进行有效集成,按多维模型组织,以便进行多角度、多层次的分析,并发现趋势。
- 前端工具:主要包括各种报表工具、查询工具、数据分析工具、数据挖掘工具以及各种基础仓库数据或数据集市的应用开发工具。
反规范化技术
规范化设计后,数据库设计者希望牺牲部分规范化来提高性能。
优点:降低连接操作的需求,降低外码和索引的数据,还可能减少表的问题,能够提高查询效率。
缺点:数据的重复存储,浪费了磁盘空间;可能出现数据的完整性问题,为了保障数据的一致性,增加了数据维护的复杂性,会降低修改速度。
具体的方法:
- 增加冗余列;
- 增加派生列;
- 重新组表;
- 水平分割表;
- 垂直分割表;