文章目录
- 6 数据库管理系统
- 6.1 数据库管理系统结构简介
- 6.2 进程结构
- 6.2.1 进程的分类
- 6.2.2 线程的由来
- 6.2.3 建立进程的过程
- 6.3 数据目录
6 数据库管理系统
6.1 数据库管理系统结构简介
数据库管理系统DBMS是数据库系统的核心。而目前市场上我们接触到的商品化DBMS大多数是关系型DBMS,简称RDBMS;小部分为对象关系型DBMS,简称ORDBMS。
我们来看一下解释执行的RDBMS结构,如下所示:
如果有学过操作系统的同学对这种结构实际上很熟悉,其中红色框框部分的内容很像是操作系统。而操作系统对外提供一层自底向上的接口,同样地,数据库也是如此。
DMBS提供给用户许多接口,这些接口有交互式接口、嵌入式接口、自然语言查询接口等诸多种类,比较大的分类即为UFI(即席访问,即交互式接口)和API。目前比较流行API的就有JDBC、ODBC等。某些程序在代码中使用到了上述的接口,当连接数据库时,数据库会将程序中使用到接口的代码抽取出对应的数据库语句,然后转换为一种最基本的数据库语言,如SQL。
当SQL被抽取出来时,首先DBMS会先检查该SQL的访问权限,检查该用户是否有权访问语法树
中所涉及的数据对象。如果授权通过,则继续执行,如果不通过则驳回访问。如应用中SQL语句要求连接数据库检查某张表,如果该用户没有权限访问这张表,则驳回请求。
结果以上的操作后,SQL语句就进入语法树进行语义分析和处理。不同类型的SQL语句对应做出不同的处理。对于DDL来说,要考虑存储路径存储方式等问题;对于DQL来说,要考虑查询效率等问题;除此之外,一些并发控制和恢复机制也需要关注。
在每个过程中,每一层都会给上一层提供一个原子操作,即原语
,如果在这里你不知道是什么,也不影响,这是操作系统中的知识。
在以上的叙述中,我们一直处于物理层外
,当进入操作系统时,就进入物理层内
了。
DBMS实际上是建立在操作系统之上的软件系统,是操作系统的用户。在操作系统中我们知道,计算机中的硬件和软件包括资源都是由操作系统来管理的。如果DBMS想要访问磁盘,就必须要通过系统调用
来请求操作系统为自己服务。
系统调用
系统调用实际上是指,当软件涉及到对资源或处理器上的请求时,就必须请求操作系统来帮忙解决,而这个请求的方式我们就叫系统调用。
如果DBMS想要访问硬盘资源,当请求操作系统后,操作系统会取来物理块
为其访问,所以物理块中解释的工作就是DBMS自己干了。
物理块
物理块是磁盘结构,你可以理解为一个磁盘是由许多物理块构成的,一个物理块能存放固定大小的资源,在后面我们会详细讲述磁盘的结构,现在先这样记住即可。
在这里要说明的是,单纯从SQL的逻辑来讲,并发控制和恢复并不是每个数据库系统都必须的,只有在大型商业的多用户访问数据库才是必须的。
6.2 进程结构
同样的,DBMS是以进程为单位,在操作系统之上运行的系统软件。DBMS的进程通常分为两类:前台进程
和后台进程
。
6.2.1 进程的分类
专为单个事务服务的DBMS核心进程(也被称为前台进程
)
每个事务都有一个与之对应的DBMS的核心进程,它是事务的执行者,并代表事务与用户和系统对话。由于DBMS核心进程可以和用户直接对话,所以我们一般也叫他前台进程。
事务是什么我们后面会讲述,现在通俗地理解就是:事务就是多个操作共同完成一件事。
为公共服务的后台进程
后台进程无法和用户直接对话,而由DBMS调用。一般我们将一些公共操作或事务无法承担的操作由后台进程来执行,如写入数据库后更新后的内容(一般交给事务提交后执行)、预先读取可能用到的物理块、异常结束事务的善后处理等。
前台进程由于是为事务服务,所以寿命和事务一样,而后台进程是常驻进程。一般不影响事务的提交,其执行时间由系统掌控,如在适当时间成批写入数据库的更新内容。
前台进程和后台进程在windows上的理解你可以理解为:前台进程就是听歌,后台进程就是你打开任务管理器然后发现后台莫名其妙多了几个和你听歌无关却随着你听歌开起的进程。
DBMS进程的通信方式如下所示,我们这里也稍作讲解:
不管我们用什么语言写的软件,当我们要调用数据库时,应用开启作为一个进程,调用数据库数据库也会创建一个核心进程,创建完成后,DBMS就会为这两个进程之间构建一个通讯的管道,在操作系统中,我们有一个pipe它是单向的通讯机制
,所以如果要实行双向通讯机制的话,我们就要再创建一个管道。这样的话,一个作为写管道
,一个作为读管道
。如图:
管道通信要求当管道中的数据写满才能取走,取空才能继续写入。当未写满数据时就要去取管道的数据时,进程会堵塞。
6.2.2 线程的由来
进程是有缺点的,对于进程来说,其创建、撤销、切换、通信的开销都较大,而且由于CPU的处理能力和内存空间的限制,计算机系统可并发运行的进程数是有限制的,如果是一个单核CPU只能并行地运行一个进程。但是如果并发的进程数过多,则进程切换频繁、系统开销增大,处理效率反而下降。操作系统一般设有并发度的限制,并且做为上限。
最后一点是,进程不利于事务共享内存空间。从以上的叙述我们可以知道,应用和进程是单连接的,也就是说,进程是有各自的独立内存空间,受操作系统保护,不能访问彼此的内存空间。
进程创建删除开销大的原因在于,创建进程时要在进程表中填入一条元组,这条元组在操作系统中我们称其为进程控制块(PCB)。对于进程撤销时,要将PCB从进程表中删除。
进程切换开销大的原因在于,在操作系统中存在虚拟内存技术,对于固定内存来说,其电脑运行的程序内存往往大于运行内存。而之所以能够如此,是因为其能通过对程序的切割,将程序所需的部分置于内存,而程序暂时不需要的部分置于磁盘,而内存中如果马上需要磁盘部分的应用数据,就需要通过一种叫做MMU(存储管理单元)来查找所在位置。如果你频繁切换进程,那就要导致操作系统每次都要修改MMU,这种修改操作在操作系统中被称为
上下文切换
,代价非常昂贵。进程通信开销大的原因在于,对于DBMS来说,其使用管道通信的方式,管道通信根据我们上面所说其必须写满才能取,取空才能写,这实际上是一种互斥的方式,效率非常慢。
在DBMS中不利于事务共享是十分不利的,因为DBMS中同一个数据可能在很多位置有用到,比如一条元组就有可能同时被数据字典、缓冲区、锁表等同时记录。
还有就是并发和并行的区别。并发是指同一时间下,CPU以极快的速度轮流为各进程服务,造成“同时”服务的假象;而并行是指同一时间下,多个CPU分别为多个进程服务,是真正意义上的”同时“。
基于上面所说,在现代操作系统中,实际上允许我们在进程之内开辟线程,用线程来作为并发运行的基本调度单位。
你可以理解为线程就像一条大电缆你剁开里面可以看到很多小电缆。
在很久以前还没有引入进程
之前,系统中的各个程序只能串行执行。比如你想要边听歌边开QQ,这是不可能做到的,只能先做一件事再做一件事。
后来引入进程后,系统中的各个程序可以并发执行。也就是说,可以同时听歌和开QQ。但是,即使引入了进程,也不能在QQ中同时视频聊天和传输文件。这是因为操作系统每一次执行都是按照进程为单位来执行的。
从上面的例子来看,进程是程序的一次执行。但是这些功能显然不可能是由一个程序顺序处理就能实现的。
有的进程可能需要“同时做很多事”,而传统的进程只能串行地执行一系列程序。为此,引入了线程
来提高并发度。
在传统中,进程是程序执行流的最小单位,也就是说,CPU每次执行任务,最少执行一个进程。而后在现在,CPU每次执行任务,最少执行一个线程,线程是进程的子集。也就是说,引入线程后,线程成为了程序执行流的最小单位。
综上所述,我们可以把线程理解为“轻量级进程”。线程
是一个基本的CPU执行单元
,也是程序执行流的最小单位
。引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如QQ视频、文字聊天、传文件)。引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。
综上所述,我们可以总结出下面几点:
- 线程的主要资源来源于进程,属于线程本身的专用资源很少。
- 描述线程的状态表(TCB)要比进程的状态表(PCB)容易的多。
- 线程之间可以通过内存通信。
- 线程切换的开销要比进程切换低的多,甚至不需要通过操作系统。
当我们开启DBMS的进程后,DBMS会立马初始化这个进程,然后出现以下的东西:
-
Daemon线程:
起一个监控的作用,他会监视应用程序访问数据库的一些请求。比如我们和SQL的ip地址和端口号连接的时候,Daemon线程就在监视是否连接成功。
-
catalogue目录:
他是一种原数据,我们存储在数据库的数据提炼的大纲数据就是目录。比如我们写select* from emp;数据库如何查看有无这张表?就是通过目录去查找。
-
封锁表:
用来控制对锁的申请,他是一个公共的资源
-
buffer缓冲区:
内存的缓冲
6.2.3 建立进程的过程
DBMS建立进程的过程如下图所示:
假如我们现在有一个应用程序,如果其想要连接数据库,它可以通过某种接口连接,拿Java写的应用程序举例,其用的就是JDBC,通过connect方法视图连接数据库时,Daemon就会捕获连接请求,从而为这个应用程序对应的进程建立一个相应的DBMS核心进程,并在两个进程之间建立一条用于进程通信的管道。建立完成后,后面的过程就如同我们在6.1所讲,结果操作后数据库把结果通过管道传回应用程序。
Daemon线程实际上在这个过程中扮演着监听的角色,一旦两个进程建立管道后其就会消失,等待下一个应用程序的进程来连接数据库。
6.3 数据目录
数据目录是一组关于数据的数据,也叫元数据。在高级程序设计语言中,程序中的数据一般容易失效,一个变量在函数用完就会被回收。而在DBMS的任务是管理大量的、共享的、持久数据。有关数据的定义和描述必须长期保存在系统中,一般把这些元数据组成若干表,称为数据目录,由系统管理和使用。
数据目录会在初始化数据库的时候由系统自动生成。数据目录是被频繁访问的数据,同时也是十分重要的数据,数据目录没有建立的时候,任何SQL无法查询,无法生效,所以,数据目录影响全局。一般DBMS不会让你更新数据目录,DBMS会自动帮你更新,他只允许你查询就够了。