如何理解SQLite软件架构

58次阅读
没有评论

共计 2498 个字符,预计需要花费 7 分钟才能阅读完成。

本篇内容主要讲解“如何理解 SQLite 软件架构”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“如何理解 SQLite 软件架构”吧!

SQLite 是一个非常受欢迎的数据库,在数据库排行榜中已经进入前十的行列。这主要是因为该数据库非常小巧,而且可以支持 Linux、Windows、iOS 和 Andriod 的主流的操作系统。

SQLite 非常简单,是一个进程内的动态库数据库。其最大的特点是可以支持不同的语言来使用,比如 C、C++、Java 等等。同时,SQLite 还是一个开源的数据库,也就是开发者可以根据自己的需求来修改数据的功能特性。

SQLite 虽然非常小巧,但功能却非常丰富,正所谓“麻雀虽小,五脏俱全”。SQLite 不仅具备基本的 SQL 特性,还具备索引、触发器、视图和事务等特性。

SQLite 的主要 API

SQLite 提供两种访问接口,一种是通过 sqlite 命令行工具,另外一种是通过动态库,也就是 API 函数。在学习 SQLite 架构之前,我们有必要对其 API 进行一个简要的介绍。其实 SQLite 的 API 很简单,主要包括三个,分别是 sqlite3_open、sqlite3_exec 和 sqlite3_close 三个函数。其中 sqlite3_exec 则是用于执行 SQL 语句的函数。

也就是说 sqlite3_exec 是 SQLite 功能的关键入口,我们后面分析代码也应该以此函数作为突破点。其它函数相对简单,也没那么重要。

SQLite 整体架构

首先我们从整体架构上介绍一下 SQLIte。其架构如图所示,包括接口层、SQL 命令处理器和存储后端等。

最为核心的不是就是 SQLite 内核了。其中包括接口层、SQL 命令处理器和虚拟机三部分。SQL 命令处理器负责对用户的 SQL 进行预处理,最终生成适用于虚拟机执行的代码。

其下是后端部分,后端部分相当于存储引擎。下面我们简要的介绍一下每个模块的功能。

(1) 接口

SQLIte 库的使用通过函数调用实现。为了避免与其它库出现冲突,SQLite 的函数都以 sqlite3 作为前缀。接口部分的实现在文件 main.c,legacy.c 和 vdbeapi.c 中。其中 main.c 中包含其主要的接口,包括 sqlite3_open、sqlite3_config 和 sqlite3_close 等等。SQLite 中最终的函数不在 main.c 中,而是在 legacy.c 中,该文件中只包含这一个接口的实现。

(2) 词法分析器

词法分析器对 SQL 语句字符串进行解析,最终生成单词 (token) 序列。并且将生成的单词序列传给解析器进行下一步的动作。该功能的具体实现在文件 tokenize.c 中,核心入口函数为 sqlite3RunParser。

(3) 解析器

SQLite 的解析器基于 Lemon 实现,它实现将 SQL 语句字符串解析成语法树。Lemon 是一个与 YACC/BISON 类似的词法分析库。该库的源代码在 tool 目录中。

(4) 代码生成器

代码生成器用于生成与 SQL 语句对应,可以在虚拟机执行的代码。代码生成器实现比较复杂,包含的文件有:build.c, delete.c, attach.c,  expr.c, insert.c, pragma.c, select.c,  auth.c 等等。通过文件名可以看出,这里很多文件其实分别对应着一个 SQL 语句,比如 delete,insert 和 select 等。

(5) 虚拟机

SQL 的具体执行在一个称为虚拟机的组件中进行的,这个在前面架构图中已经有所展示。虚拟机执行的代码有前面代码生成器产生。虚拟机的实现在文件 vdbe.h 和 vdbe.c 中。

(6) B- 树

SQLite 的数据通过 B 树进行组织管理。每个表或者索引都有一个对应的 B 树。所有的 B 树存储在一个数据库文件中。B 树的具体实现在 btree.c 和 btree.h 文件中。

(7) 页缓存

SQLite 的文件被划分为等份大小,B 树也是以该大小为粒度来对数据进行管理。页缓存是该粒度对应的内存内容,通过该内存实现对数据块的读写等访问。页缓存相关的实现在 pager.c 和 pcache.c 等文件中。

(8) 操作系统接口

SQLite 是一个跨平台的数据库,其存储数据需要兼容 Windows 和 Linux 的文件系统 API。为了方便,SQLite 实现了一个抽象层。这样对于 SQLite 业务逻辑来说,只需要调用该抽象层的接口即可,而不用关心操作系统。

(9) 基础库

包含一个被各个模块都可能使用到的基础库,比如内存分配,字符串处理等。

SQLite 文件格式

前文我们简要的介绍了一下 SQLite 的软件架构以及每个组件的基本功能。接下来我们介绍一下数据库文件的相关功能。

在 SQLite 中一个文件承载着一个数据库实例,这个文件称为主库文件(main database  file)。除了主库文件外,还可能有一些其它文件,比如用于事务的日志文件等。本文主要集中介绍主库文件,其它文件后续介绍。

(1) 页

数据库文件由多个页构成,每个页的大小在 512 到 65536 字节之间,且大小必须是 2 的幂。页通过编号进行标记,起始值为 1,最大编号为 2 的 31 次幂 -2。页的默认大小是 4KB,本文以默认大小为例进行介绍。

在数据库中的每个页都有一个特定的用途,这些用途包括:

锁字节页(Lock-byte page)

剩余 页

B 树 页

指针映射页

有效负载溢出页

数据库文件的第一个页是比较特殊的,它包含整个数据库文件的描述信息,这里称为数据库头信息。

(2) 数据库头

数据库头包含 100 个字节的内容,其中每一个成员的偏移,大小和功能如下图所示。

我们可以创建一个数据库实例,然后对照文件内容与数据库头的格式进行理解。比如数据库头的第一个成员为一个魔数,用于标识该文件为 SQLite 数据库文件及版本。在下图中可以找到该信息,可以看出两者完全匹配(SQLite  format 3)。

除了上述数据库头的格式外,每个不同的页都有不同的布局。

到此,相信大家对“如何理解 SQLite 软件架构”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-27发表,共计2498字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)