数据库的四个基本概念
1、数据
数据库中存储基本对象,像文字、图像什么的。
数据和其语义是密切相关的,比如93是分数。
所以数据是有结构的,能知道它的语义。
2、数据库
是长期存储在计算机内、有组织的、可共享的大量数据的集合。
建立数据库有很多好处:可以收集并抽取大量数据,保存并可以进一步加工处理,抽取有用的信息。比如淘宝的推荐系统。
数据库的基本特征:
(1)按一定数据模型组织。
(2)可共享、冗余小、易扩充(现在一堆数据,A和B在用,如果C也想用只需要获得授权就能用了)
(3)数据独立性高。
这里重点说一下数据独立性:分为 物理独立性 和 逻辑独立性。
数据独立性和数据库的发展过程是密切相关的,因为在早期使用文件系统的时候,文件系统的这两部分独立性太垃圾了,用起来巨麻烦。所以前辈们集思广益,想出了这两种独立性,所以下面的例子主要是和文件系统(以C语言的文件访存为例)比较加深对数据独立性的理解和对前辈们的叹服。
物理独立性
:用户的应用程序与数据库中的数据的物理存储是相互独立的。即:数据在数据库中怎么存储,应用程序不需要知道。
比如说:原来C语言中想要访存C盘User中的文件,File* file = fopen(”C:\user\…”);那么我必须要知道这个文件到底存储在哪里,假如现在这个文件跑到E盘的某个目录下,那么我就必须要修改这个C语言语句了。
但是有了数据库之后,数据库可能就告诉我这个文件在database虚拟目录下,不管它底层从C盘跑到E盘还是从E盘跑到D盘,我在database这个虚拟目录都能找到。
在存储的时候,数据库会建立在操作系统的文件系统之上,利用B+树等数据结构对数据进行存储。假如没有数据库,在找数据的时候B+树有B+树的找法,数组有数组的找法:就像找B+树的时候也不能像数组那样顺序查找,那这个时候就需要根据它的数据结构去找数据了,就要修改应用程序了。
逻辑独立性
:用户的应用程序与数据库的逻辑结构是相互独立的。即,当数据的逻辑结构改变时,用户程序也可以不变。
什么意思呢?假如现在从对应的文件取出了数据,假如按C语言的处理方式,这玩意是一个结构体。
举个例子,假设要查询学生信息,结构体如下:
Struct student{
Int ID;
Char name;
Int age;
}
Struct student tmp = SQL.get(); //获得某一个信息(随便瞎写的代码)
但是呢,我现在在数据库里,又加了“性别”这个结构,即结构体变为了
Struct student{
Int ID;
Char name;
Int age;
Char sex;
}
那我原来的程序tmp这个变量接收这个结构体就会出错了,那我就要修改我的程序了。
但是因为数据库内部有了一定的处理,所以它用了一种方法,可以让数据库改变了对应的逻辑结构(比如表结构),我们的程序也不用该改变(就算你把姓名删了,它没有了,也会抛出对应的异常告知程序)。
就相当于可以为所欲为的取数据了。(邪恶笑声:哈哈哈哈)
3、数据库管理系统
介于用户和操作系统之间的数据管理软件。
是一个大型复杂的软件系统。
可以科学地组织和存储数据、高效的获取和维护数据。
数据库相当于就是硬件设备,比如一堆磁盘什么的,怎么样去存,怎样去取,怎么样保证数据独立性,都是数据库管理系统要干的。
数据库管理系统主要功能:
(1)定义数据:比如提供数据定义的语言,然后用这个语言去定义数据库中的数据对象。Int、varchar
(2)数据组织、存储和管理:数据之间的联系怎么实现?怎么提高存取效率(比如采用B+树)等。
(3)数据操作:增删改查,用SQL语言操作。
(4)事物管理和运行管理:怎么保证事物不会中断,怎么保证发生故障后能够恢复数据库。
(5)数据库建立和维护:性能监视等。
(6)数据控制:1、数据安全性保护 2、数据完整性检查 3、并发控制 4、数据库恢复。
(7)其他功能:与网络其他软件通信等。
4、数据库系统
数据库系统 = 数据库 + 数据库管理系统 + 应用程序 + 数据库管理员。
数据库系统的三级模式和两级映像
从内到外分别是:内模式——模式——外模式
内模式
:数据的物理结构和存储方式的描述。比如用hash方法存储(记录存储方式),索引方式是B+树(索引组织方式),是否压缩、加密,是否支持可变长记录等。模式
:所有用户的公共数据视图,描述了数据库全体数据的逻辑结构和特征描述。(相当于在管理员角度看)外模式
:一部分的数据试图,表述用户使用的局部数据的逻辑结构和特征的描述。
两级映像:外模式/模式映像、模式/内模式映像。
在理解了数据库基本概念中的数据库部分的逻辑独立性和物理独立性之后,两级映像其实就是对这两个独立性的具体实现。
外模式/模式映像
:应用程序根据外模式编写,当模式改变时,数据库管理人员只需要对这个映像改变,使得外模式不变,就可以让应用程序不必修改,保证了数据的逻辑独立性。模式/内模式映像
:定义了数据全局逻辑结构和存储结构之间的对应关系。比如栈这个逻辑结构在实际存储的时候采用顺序存储。当存储模式改变了,比如改成了链式存储,数据库管理人员通过修改这个映像,可以使得模式保持不变。
关系数据库
关系模型的基本概念
1、基本关系的名词(关系、元组等)
域
:具有相同数据类型的值的集合候选码
:若关系中某一属性组(注意是’组’)的值能唯一标识一个元组,而其子集不能,则称该属性组为候选码。主属性
:候选码中的属性。非主属性
:不包含在任何候选码中的属性。关系
:一个关系对应通常说的一张表。元组
:表中的一行属性
:表中的一列分量
:元组中的一个属性值
2、基本关系的六条性质
- (1)行顺序无所谓(行与行之间交换顺序无所谓)
- (2)列顺序无所谓(列与列之间交换顺序无所谓)
- (3)列是同质的(一列分量是同一类型,来自同一个域)
- (4)不同的列可出自同一个域(比如老师和学生都属于学校人员这个域)
- (5)任意两个元组候选码不同
- (6)分量必须取原子值(不能表中套表,1NF内容)
3、基本关系操作(想操作哪个查一下就出来了)
- 选择
- 投影
- 并
- 差
- 笛卡尔积
关系模型中三种完整性约束
关系模型中的三种完整性约束有:
- 1.实体完整性
- 2.参照完整性
- 3.用户定义完整性
实体完整性:主属性不能为空。
(参照完整性定义比较复杂,这里简单点说)
参照完整性:一个关系的外码必须等于另一个关系某个元组的主码值或者**整个外码都是空(如果是属性组的话,里面全是空的)**的。
解释一下:
假如现在有
学生表:学生(学号,姓名,专业课名,专业课教师)
专业课表:专业课(专业课名,专业课教师,专业课微信群)
学生表中,学号是主码,专业课是外码;专业课表中,专业课名和专业课教师共同构成主码。
假设专业课表内容为:
(数据结构,华老师,123456)
(操作系统,頔老师,654321)
构造表的时候:只有以下两种情况
(123456,曲某,数据结构,华老师)(此时在专业课表中有相应的内容)
(123456,曲某,空,空)
不能出现(123456,曲某,数据结构,頔老师)(在专业课表中不存在的内容)
这样类似的情况。
用户自定义完整性:用户自己定义的完整性,比如银行系统中账户余额不能小于0.
数据库优化
关系查询优化
1、代数优化
根据关系代数的等价变换规则将关系代数表达式转化为等价的处理代价较小的表达式。比如说 x2 + 2xy + y2 如果直接计算需要四次乘法两次加法;但是写成 (x+y)2 只需要一次加法一次乘法。
2、物理优化
通过选择高效合理的存取路径和底层操作算法来提高查询效率。比如说基于规则的优化RBO
、基于代价的优化CBO
等。
基于规则的优化(Rule):简单理解就是数据库执行一条SQL语句的时候必须遵循预先定义好的一系列规则(排名越靠前的执行引擎认为效率越高),是一种经验式的方法。比如1是索引方式 2是顺序方式 它默认觉得1比2好。
基于代价的优化(Cost):根据表的统计信息(比如长度、大小、索引情况),计算每一种方案的代价,选那个代价最小的。
关系数据理论
先理解X->Y的含义:叫做Y函数依赖于X。
比如说 学号->年龄 意思是 年龄由学号决定的,一个学号只对应一个年龄。
数据依赖
-
(1)函数依赖
-
(I)完全函数依赖
X->Y,且对于X的任何一个真子集X’,都有Y不依赖于X’。简单点说,X是Y的最小函数依赖,比如说 Y = 学生选的专业课 由 X =(专业名,上课老师)共同决定,那么X中任何真子集如专业名都无法单独决定Y. -
(II)部分函数依赖
X->Y,且Y不完全函数依赖于X。比如 Y = 年龄 由 X =(学号,姓名)共同决定,但是 X’ = (学号)也可以决定Y,所以X->Y是部分函数依赖。 -
(III)传递函数依赖
这个定义太复杂不给定义了,传递依赖有点类似:A->B, B->C所以A->C。(注意X不依赖于Y,不然是直接函数依赖)
举个例子:
学号->院系,院系->姓名,那么姓名传递依赖于学号,即学号->姓名。
-
-
(2)多值依赖:不做讨论。
三大范式
-
1NF:关系中每一个分量必须是不可分的数据项。即表中不能有表,如下图所示:
-
2NF:1NF基础上,关系的每个非主属性完全函数依赖于任何一个候选码。2NF解决了非主属性部分依赖的问题。意思就是2NF中不能出现像前面部分函数依赖例子那样出现部分依赖的情况。
-
3NF及BCNF:
3NF
:设关系模式R<U,F>属于1NF,若R中不存在这样的码X,属性组Y及非主属性Z(Z⊊Y)使得X->Y,Y->Z成立,Y->X。3NF在2NF基础上解决了非主属性的传递依赖。(在3NF中不能有传递依赖)
BCNF
:关系模式R<U,F>属于1NF,若X->Y且Y⊊X时X必含有码,则关系模式属于BCNF。BCNF在3NF基础上消除了主属性中的部分依赖。关于BCNF范式稍微解释一下:什么叫主属性中的部分依赖。
即所有主属性对每一个不包含它的码也是完全函数依赖。举个例子:
设关系模式R(Stu,Course,Teacher),Stu表示学生,Course表示课程,Teacher表示老师:假设老师只教一门课,一门课有多个老师,学生选一门课就有一个老师,由语义可以得出:
(Stu,Course)-> Teacher
(Stu,Teacher)-> Course
(Teacher)-> Course
其中(Stu,Course)和(Stu,Teacher)都是候选码,所以Stu、Course和Teacher都是主属性(这里和2NF、3NF做区分,那都是针对非主属性的)由部分依赖的定义,X = (Stu,Teacher),X的真子集是X’ = (Teacher),Y = Course,存在X->Y且X’->Y,所以Y部分依赖于X。其实就和2NF非常类似,只不过把非主属性变成主属性了。
- 4NF和5NF不做讨论。
注意:2NF、3NF和BCNF都是在1NF基础上定义的,虽然它们解决的内容看上去是递进的——若R属于3NF,R一定属于2NF。