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

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

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

SQLite的主要API

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

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

SQLite整体架构

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

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

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

接口

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

词法分析器

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

资料直通车:最新Linux内核源码资料文档+视频资料

内核学习地址:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

解析器

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

代码生成器

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

虚拟机

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

B-树

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

页缓存

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

操作系统接口

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

基础库

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

SQLite文件格式

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

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

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

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

  • 锁字节页(Lock-byte page)
  • 剩余 页
  • B树 页
  • 指针映射页
  • 有效负载溢出页

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

数据库头

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

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

除了上述数据库头的格式外,每个不同的页都有不同的布局。限于篇幅,本文暂时不过多介绍,后面结合实例专门写一篇文章介绍各种不同的页的布局。

知其然更要知其所以然,聊聊SQLite软件架构相关推荐

  1. 预测师的随想系列五:知其然重要,知其所以然更重要

    五个理由 1.你不了解的东西随便用了,出问题谁来负责,你. 2.知其然是基础,知其所以然是更高层次的追求. 3.打造技术领导力,你要比别人懂得更深更多才可以做领导. 4.长期知其然,就可能再也无法跳出 ...

  2. STL之string类:知其然,需知其所以然

    目录 前言 一,构造及初始化 1.1constuct类函数 1.2构造函数及其模拟实现 1.3拷贝构造及其模拟实现 1.4赋值操作符 1.5string类的swap接口 二,迭代器 2.1初识迭代器即 ...

  3. 知其然,而不知其所以然

    求一个题:find dy/dx for the function y defined implicitly by y^4+xy=4 at x=3, y=1. 做的时候将D(xy) 计算为y. 其实自己 ...

  4. Spring @Autowired 知其然定需知其所以然 第一弹

    @Autowired 想必大家都不陌生吧,基本上是日常开发必用,本系列将逐一对它进行记录说明,层层剖析.欢迎大家留言讨论,感谢支持~ 文章目录 作用范围 介绍一下@Autowired @Autowir ...

  5. 招商银行的“金融+知识”:知其然,更要知其所以然

    一个更加成熟.健康的金融市场,需要更加成熟.理性的用户来焕发勃勃生机:一个具备公信力的金融机构所做出的持续化.专业化金融知识输出,也将大大增加与用户之间的连接和信任. 这种相互成就的关系,正是服务1亿 ...

  6. 感想篇:7)知其然与知其所以然,KnowHow与KnowWhy

    本章目的:探究--知其然与知其所以然,KnowHow与KnowWhy. 1.Know-How体系与代价: 100多年的汽车研发历史表明,企业只有开发过两代车以上才能逐步建立和完善Know-How体系. ...

  7. 知其然,知其所以然之Java基础系列(一)

    相信大家在最初接触Java基础学习的时候,也只是跟着课本上的描述学习,知其然,不知所以然,要想成为一个Java老鸟,不仅要学会怎么用,也要知道为何这么用.在Java基础系列的博客中,我会列举一系列大家 ...

  8. No.2第一章 启航 | Flink 知其然,知其所以然

    |文末 点击[在看]留言 反馈 | Flink知其然部分共有三个章节,其中 第一章 启航 部分会 从Flink的应用场景切入,让大家清楚的判断自己的业务场景是否适合使用Flink,同时介绍Flink的 ...

  9. 【转】可解释推荐系统:知其然,知其所以然

    原文标题:"可解释推荐系统:知其然,知其所以然" 原文地址:可解释推荐系统:知其然,知其所以然 又是需要学习的地方 近几年,人工智能的可解释性问题受到了来自政府.工业界和学术界的广 ...

最新文章

  1. 深度全解卷积神经网络(附论文)
  2. 2010年8月blog汇总:敏捷个人和OpenExpressApp之建模支持
  3. vba字典合并单元格为空_VBA合并单元格求和处理套路
  4. java list用法 包,java list用法示例详解
  5. JSP简介及入门(含Eclipse for Java EE及Tomcat的配置)
  6. mysql 关闭锁_mysql数据库取消锁
  7. 一个小技巧助您减少if语句的状态判断
  8. Nginx动静分离实现负载均衡
  9. 容器编排技术 -- Kubernetes kubectl create poddisruptionbudget 命令详解
  10. JavaScript Tip之:用和||来模拟if-else
  11. CentOS 6.9下的iptables在本机用DNAT转发指定IP到内网IP无效的问题解决(127.0.0.1)
  12. 使用js生成条形码以及二维码
  13. conda: command not found
  14. AI的螺旋式上升?今日头条AI掌门人马维英离职,“重返”清华从事培育科研工作
  15. matlab 线型、标记、颜色
  16. php 单词替换,单词替换 - Shiyin's note
  17. ubuntu txt文件打开乱码怎么恢复正常
  18. 当前 .NET SDK 不支持将 .NET Core 2.2 设置为目标。请将 .NET Core 2.1 或更低版本设置
  19. 低延迟平价游戏蓝牙耳机推荐,2021值得入手的五款品牌蓝牙耳机
  20. 论文研读 —— 6. ImageNet Classification with Deep Convolutional Neural Networks (2/3)

热门文章

  1. Yosemite作用
  2. linux中db2创建存储过程,db2构建存储过程过程
  3. 在Oracle中,如何定时删除归档日志文件?
  4. United Plugins Total Bundle for Mac(联合音频插件合集包)
  5. 应届生报考MEM时要注意了!非全不是你的菜!
  6. ylmf linux y1.15(ubuntu),Ylmf Linux Y1.15 XP下硬盘安装
  7. 【原创】单片机入门《八集视频真正入门单片机系列视频》
  8. vuejs管理系统模板_2020年22种最佳VueJS管理员仪表板模板
  9. VC,PE和Hedge Fund
  10. LAZADA店铺运营分享:lazada后台有没有数据分析?生意参谋如何使用!