知其然更要知其所以然,聊聊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软件架构
SQLite是一个非常受欢迎的数据库,在数据库排行榜中已经进入前十的行列。这主要是因为该数据库非常小巧,而且可以支持Linux、Windows、iOS和Andriod的主流的操作系统。 SQLite非常简单,是一个进程内的动态库数据库。其最大的特点是可以支持不同…...
微服务架构的演变
文章目录1.1 系统架构的演变过程1.1.1 单体应用架构1.1.2 垂直应用架构1.1.3 分布式架构1.1.4 SOA架构1.1.5 微服务架构1.2 微服务架构设计原则1.2.1 AKF拆分原则1.2.1.1 X轴扩展(水平复制)1.2.1.2 Y轴扩展(模块拆分)1.2.1.3 Z轴扩…...
使用html-to-image代替html2canvas,结合jspdf实现下载pdf(下载截图下载前端dom元素)
一、问题 一开始的时候,准备使用html2canvasjspdf来实现的,但是遇到了一个麻烦的问题,在其他项目中使用html2canvas没有任何问题,但是在要开发的项目中使用,就给我报错,是真滴烦。 html2canvas报错 Uncau…...
云环境渗透测试的重要性
🌕写在前面 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 ✉️今日分享: “在这个世上,除了极稀少的例外,我们其实只有两种选择:要么是孤独,要么就是庸俗。” 随着云计…...
ROS2 入门应用 请求和应答(Python)
ROS2 入门应用 请求和应答(Python)1. 创建功能包1. 创建功能包2. 创建源文件2.1. 服务端2.2. 客户端3. 添加依赖关系4. 添加入口点5. 编译和运行1. 创建功能包 1. 创建功能包 在《ROS2 入门应用 工作空间》中已创建和加载了ros2_ws工作空间 在《ROS2 入…...
是德Keysight E4991A/e4991B射频阻抗/材料分析仪
Keysight E4991A 射频阻抗/材料分析仪提供终极阻抗测量性能和强大的内置分析功能。它将为评估 3 GHz 范围内组件的组件和电路设计人员的研发提供创新。E4991A 使用 RF-IV 技术,而不是反射测量技术,可在宽阻抗范围内进行更精确的阻抗测量。基本阻抗精度为…...
这才是计算机科学_人工智能
人工智能一、前言二、ML2.1 分类2.1.1 决策树2.2.2 支持向量机2.2.3 人工神经网络三、计算机视觉3.1 Prewitt算子3.2 Viola-Jones 人脸检测算法3.3 卷积神经网络四、自然语言处理4.1 知识图谱4.2 语音识别一、前言 之前讲了计算机从发展到现在的过程,计算机很适合做…...
DFS深度优先搜索—Java版
递归三要素 递归的定义 递归的拆解 递归的出口 什么时候使用DFS? 深度回溯问题(DFS与回溯区别不大) 二叉树问题 组合、排列问题 找方案问题(解空间是一棵树或者图,需要自行构造图/树) 图的搜索问题…...
RAY - 小记
文章目录关于 RAYRAY 结构关于 RAY Ray is a unified framework for scaling AI and Python applications. Ray consists of a core distributed runtime and a toolkit of libraries (Ray AIR) for accelerating ML workloads. RAY 是一个简单、通用的分布式计算框架。 RAY 解…...
金三银四软件测试工程师面试题(含答案)
前言:此文专门记载本人平时面试以及收藏的面试题目,如果有错误之处请及时指正,谢谢! 1、python的数据类型有哪些 答:Python基本数据类型一般分为:数字、字符串、列表、元组、字典、集合这六种基本数据类…...
Python 连接数据源与邮件功能(九)
文章目录一、概述二、Python 连接数据源1)Python MySQL 基础操作1、部署MySQL2、MySQL Connector 库【1】安装 mysql-connector-python 库【2】连接 MySQL【3】增加数据【4】查询数据【5】更新数据【6】删除数据2、PyMySQL 库【1】安装 PyMySQL 库【2】连接 MySQL【…...
网站如何锁定用户,超级浏览器有办法解决吗?
随着全球开放,跨境电商人纷纷开启了2023年的搞钱之旅,很多期待着在新的一年大干一场。但前事不忘后事之师,2022年跨境生意全面沦陷,其实除了大环境的因素之外,还有一个很重要的原因是,各个平台都开始实行非…...
Ubuntu下使用Wine运行HBuilderX
安装完wine后,在HbuilderX的目录中打开终端,直接输入wine HBuilderX.exe命令,启动过程中会提示安装wine-mono组件,点击安装按钮下载安装该组件,该组件下载速度慢,需要等待特别长时间。 安装完毕后&…...
如何高效远程维护分布在海外的中大型智能设备?
一、行业需求 随着越来越多的企业进行全球化经营,设备制造商和系统集成商的设备分布到全球各地,数量多而且分散,传统的设备运维方式,面临着出差成本高,工作效率低,服务不及时等问题,客户常常因…...
【双指针问题】LeetCode 925. 长按键入
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
APP测试中IOS和Android的区别,有哪些注意点?
01、常识性区别 02、导航方式 iOS:Tab放在页面底部,不能通过滑动来切换,只能点击。也有放在上面的,也不能滑动,但有些Tab本身可以滑动,比如天猫的。还有新闻类的应用。 Android:一般放在页面…...
2019蓝桥杯真题平方序列(填空题) C语言/C++
题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 小明想找到两个正整数 X 和 Y,满足2019<X<Y;2019^2, X^2, Y^2组成等差数列。 请你求出在所有可能的解中,XY 的最小值是多少?…...
vue中,给一个URL地址,利用FileSaver.js插件下载文件到本地
①首先下载 FileSaver.js 插件 npm install file-saver --save ②在需要的.vue页面引入 import { saveAs } from file-saver 在HTML中引入 <script src"https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> //Fil…...
从0开始学python -34
Python3 输入和输出-2 读和写文件 open() 将会返回一个 file 对象,基本语法格式如下: open(filename, mode)filename:包含了你要访问的文件名称的字符串值。mode:决定了打开文件的模式:只读,写入,追加等。…...
瑞典军事研究:从认知心理学的视角探讨军事创新进程
来源:Military Innovation as the Result of Mental Models of Technology 《摘要》 政治紧张局势的加剧和技术发展的进步促使Scandinavian 国家(斯堪的纳维亚半岛,欧洲最大的半岛,有挪威、瑞典两国以及芬兰北端的一小部分。&am…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
