知其然更要知其所以然,聊聊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进行预处理,最终生成适用于虚拟机执行的代码。
其下是后端部分,后端部分相当于存储引擎。下面我们简要的介绍一下每个模块的功能。
接口
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.c, delete.c, attach.c, expr.c, insert.c, pragma.c, select.c, auth.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.你不了解的东西随便用了,出问题谁来负责,你. 2.知其然是基础,知其所以然是更高层次的追求. 3.打造技术领导力,你要比别人懂得更深更多才可以做领导. 4.长期知其然,就可能再也无法跳出 ...
- STL之string类:知其然,需知其所以然
目录 前言 一,构造及初始化 1.1constuct类函数 1.2构造函数及其模拟实现 1.3拷贝构造及其模拟实现 1.4赋值操作符 1.5string类的swap接口 二,迭代器 2.1初识迭代器即 ...
- 知其然,而不知其所以然
求一个题:find dy/dx for the function y defined implicitly by y^4+xy=4 at x=3, y=1. 做的时候将D(xy) 计算为y. 其实自己 ...
- Spring @Autowired 知其然定需知其所以然 第一弹
@Autowired 想必大家都不陌生吧,基本上是日常开发必用,本系列将逐一对它进行记录说明,层层剖析.欢迎大家留言讨论,感谢支持~ 文章目录 作用范围 介绍一下@Autowired @Autowir ...
- 招商银行的“金融+知识”:知其然,更要知其所以然
一个更加成熟.健康的金融市场,需要更加成熟.理性的用户来焕发勃勃生机:一个具备公信力的金融机构所做出的持续化.专业化金融知识输出,也将大大增加与用户之间的连接和信任. 这种相互成就的关系,正是服务1亿 ...
- 感想篇:7)知其然与知其所以然,KnowHow与KnowWhy
本章目的:探究--知其然与知其所以然,KnowHow与KnowWhy. 1.Know-How体系与代价: 100多年的汽车研发历史表明,企业只有开发过两代车以上才能逐步建立和完善Know-How体系. ...
- 知其然,知其所以然之Java基础系列(一)
相信大家在最初接触Java基础学习的时候,也只是跟着课本上的描述学习,知其然,不知所以然,要想成为一个Java老鸟,不仅要学会怎么用,也要知道为何这么用.在Java基础系列的博客中,我会列举一系列大家 ...
- No.2第一章 启航 | Flink 知其然,知其所以然
|文末 点击[在看]留言 反馈 | Flink知其然部分共有三个章节,其中 第一章 启航 部分会 从Flink的应用场景切入,让大家清楚的判断自己的业务场景是否适合使用Flink,同时介绍Flink的 ...
- 【转】可解释推荐系统:知其然,知其所以然
原文标题:"可解释推荐系统:知其然,知其所以然" 原文地址:可解释推荐系统:知其然,知其所以然 又是需要学习的地方 近几年,人工智能的可解释性问题受到了来自政府.工业界和学术界的广 ...
最新文章
- 深度全解卷积神经网络(附论文)
- 2010年8月blog汇总:敏捷个人和OpenExpressApp之建模支持
- vba字典合并单元格为空_VBA合并单元格求和处理套路
- java list用法 包,java list用法示例详解
- JSP简介及入门(含Eclipse for Java EE及Tomcat的配置)
- mysql 关闭锁_mysql数据库取消锁
- 一个小技巧助您减少if语句的状态判断
- Nginx动静分离实现负载均衡
- 容器编排技术 -- Kubernetes kubectl create poddisruptionbudget 命令详解
- JavaScript Tip之:用和||来模拟if-else
- CentOS 6.9下的iptables在本机用DNAT转发指定IP到内网IP无效的问题解决(127.0.0.1)
- 使用js生成条形码以及二维码
- conda: command not found
- AI的螺旋式上升?今日头条AI掌门人马维英离职,“重返”清华从事培育科研工作
- matlab 线型、标记、颜色
- php 单词替换,单词替换 - Shiyin's note
- ubuntu txt文件打开乱码怎么恢复正常
- 当前 .NET SDK 不支持将 .NET Core 2.2 设置为目标。请将 .NET Core 2.1 或更低版本设置
- 低延迟平价游戏蓝牙耳机推荐,2021值得入手的五款品牌蓝牙耳机
- 论文研读 —— 6. ImageNet Classification with Deep Convolutional Neural Networks (2/3)
热门文章
- Yosemite作用
- linux中db2创建存储过程,db2构建存储过程过程
- 在Oracle中,如何定时删除归档日志文件?
- United Plugins Total Bundle for Mac(联合音频插件合集包)
- 应届生报考MEM时要注意了!非全不是你的菜!
- ylmf linux y1.15(ubuntu),Ylmf Linux Y1.15 XP下硬盘安装
- 【原创】单片机入门《八集视频真正入门单片机系列视频》
- vuejs管理系统模板_2020年22种最佳VueJS管理员仪表板模板
- VC,PE和Hedge Fund
- LAZADA店铺运营分享:lazada后台有没有数据分析?生意参谋如何使用!