SQLite的架构(十一)

返回:SQLite---系列文章目录

上一篇:SQLite下一代查询规划器(十)

下一篇:SQLite---系列文章目录

介绍

本文档介绍SQLite库的架构。 这里的信息对那些想要了解或 修改SQLite的内部工作原理。

接口SQL 命令处理器虚拟机B-树呼叫器操作系统接口分词器解析 器法典发电机公用事业测试代码核心后端SQL 编译器辅料

附近的图表显示了SQLite的主要组件 以及它们如何互操作。下面的文字 解释了各个组件的角色。

概述

SQLite 的工作原理是将 SQL 文本编译为字节码,然后运行 使用虚拟机的字节码。

sqlite3_prepare_v2() 和相关接口充当编译器 用于将 SQL 文本转换为字节码。sqlite3_stmt对象是 实现单个字节码程序的容器 SQL 语句。sqlite3_step() 接口传递字节码程序 进入虚拟机,并运行程序,直到它完成, 或形成一行要返回的结果,或遇到致命错误,或被中断

接口

大部分 C 语言接口都可以在源代码中找到 文件 main.clegacy.cvdbeapi.c,尽管某些例程是 分散在他们可以访问数据的其他文件中 具有文件范围的结构。 sqlite3_get_table() 例程在 table.c 中实现。 sqlite3_mprintf() 例程位于 printf.c 中。 sqlite3_complete() 接口位于 complete.c 中。 TCL 接口tclsqlite.c 实现。

为避免名称冲突,所有外部 SQLite 库中的符号以前缀 sqlite3 开头。 那些供外部使用的符号(换句话说, 那些构成 API for SQLite 的符号)添加下划线,以及 因此,从sqlite3_ 开始。扩展 API 有时会添加 下划线前的扩展名;例如:sqlite3rbu_sqlite3session_

分词器

当要计算包含 SQL 语句的字符串时,它是 首先发送到分词器。 分词器中断 将 SQL 文本转换为令牌并传递这些令牌 一个接一个地到解析器。分词器是手动编码的 文件 tokenize.c.

请注意,在此设计中,分词器调用分析器。人 熟悉YACC和BISON的人可能习惯于做事 另一种方式 - 让解析器调用分词器。拥有 不过,分词器调用解析器更好,因为它可以制作 线程安全,它运行得更快。

解析 器

解析器根据 他们的背景。SQLite 的解析器是使用 Lemon 解析器生成器生成的。 Lemon 的工作与 YACC/BISON 相同,但它使用 一种不同的输入语法,不易出错。 Lemon 还生成了一个可重入且线程安全的解析器。 Lemon 定义了非终端析构函数的概念,所以 当遇到语法错误时,它不会泄漏内存。 驱动 Lemon 并定义 SQL 语言的语法文件 SQLite 理解的内容可以在 parse.y 中找到。

因为 Lemon 是一个在开发机器上通常找不到的程序, Lemon 的完整源代码(只有一个 C 文件)包含在 "tool"子目录中的 SQLite 分发。

代码生成器

解析器将令牌组装到解析树中后, 代码生成器运行以分析解析树并生成执行 SQL 语句工作的字节码预准备语句对象是此字节码的容器。 代码生成器中有许多文件,包括:attach.cauth.cbuild.cdelete.cexpr.cinsert.cpragma.cselect.ctrigger.cupdate.cvacuum.cwhere.c、wherecode.cwhereexpr.c。 在这些文件中,大多数严肃的魔术都发生了。expr.c 处理表达式的代码生成。where*.c 处理 WHERE 子句的代码生成 SELECT、UPDATE 和 DELETE 语句。文件 attach.cdelete.cinsert.cselect.ctrigger.c update.cvacuum.c 处理代码生成 对于具有相同名称的 SQL 语句。(每个文件都调用例程 必要时在 expr.cwhere.c 中。所有其他 SQL 语句是从 build.c 中编码出来的。 auth.c 文件实现了 sqlite3_set_authorizer() 的功能。

代码生成器,尤其是 where*.cselect.c 中的逻辑,有时称为查询规划器。对于任何特定的 SQL 语句,可能有 成百上千或数百万种不同的算法进行计算 答案是。查询计划器是一个 AI,它努力选择 这数百万种选择中的最佳算法。

字节码引擎

代码生成器创建的字节码程序由 虚拟机。

虚拟机本身完全包含在单个 源文件 vdbe.cvdbe.h 头文件定义接口 在虚拟机和 SQLite 库的其余部分以及 vdbeInt.h 之间,vdbeInt.h 定义了 对虚拟机本身是私有的。 其他各种 vdbe*.c 文件是虚拟机的帮助程序。 vdbeaux.c 文件包含虚拟使用的实用程序 机器和接口模块由库的其余部分用于 构造 VM 程序。vdbeapi.c 文件包含外部 虚拟机的接口,例如 sqlite3_bind_int()sqlite3_step()。个人价值观 (字符串、整数、浮点数和 BLOB)存储 在名为"Mem"的内部对象中,该对象由 vdbemem.c 实现。

SQLite 使用对 C 语言例程的回调来实现 SQL 函数。 甚至内置的 SQL 函数也是以这种方式实现的。大多数 内置的 SQL 函数(例如:abs()count()substr() 等)可以在 func.c 源代码中找到 文件。 日期和时间转换函数可在 date.c 中找到。 实现了一些函数,例如 coalesce()typeof() 作为字节码直接由代码生成器提供。

B-树

SQLite 数据库使用 B 树实现在磁盘上维护 在 btree.c 源文件中找到。单独的 B 树用于 数据库中的每个表和每个索引。所有 B 树都存储在 相同的磁盘文件。文件格式详细信息稳定且定义明确,并且 保证向前迈进兼容。

B-tree 子系统和 SQLite 库的其余部分的接口 由头文件 btree.h 定义。

页面缓存

B-tree 模块以固定大小从磁盘请求信息 页面。默认page_size为 4096 字节,但可以是 两个介于 512 和 65536 字节之间。 页面缓存负责读取、写入和 缓存这些页面。 页面缓存还提供回滚和原子提交抽象 并负责数据库文件的锁定。这 B-tree 驱动程序从页面缓存中请求特定页面并通知 想要修改页面或提交或回滚时的页面缓存 变化。页面缓存处理所有混乱的细节,以确保 快速、安全、高效地处理请求。

主页面缓存实现位于 pager.c 文件中。WAL 模式逻辑位于单独的 wal.c 中。内存中缓存由 pcache.cpcache1.c 文件实现。 页面缓存子系统之间的接口 SQLite 的其余部分由头文件 pager.h 定义。

操作系统接口

为了提供跨操作系统的可移植性, SQLite 使用一个名为 VFS 的抽象对象。每个 VFS 都提供方法 用于打开、读取、写入和关闭磁盘上的文件,以及其他 特定于操作系统的任务,例如查找当前时间或获取随机性 初始化内置伪随机数生成器。 SQLite 目前为 unix(在 os_unix.c 文件中)和 Windows(在 os_win.c 文件中)提供 VFS。

公用事业

内存分配、无大小写字符串比较例程、 可移植文本到数字转换例程和其他实用程序 位于 util.c 中。 解析器使用的符号表由找到的哈希表维护 在 hash.c 中。utf.c 源文件包含 Unicode 转换子例程。 SQLite 有自己的 printf() 私有实现(使用 一些扩展)在 printf.c 和它自己的 random.c 中的伪随机数生成器 (PRNG)。

测试代码

源代码树的"src/"文件夹中名称以 test 开头的文件仅用于测试,不包含在标准中 库的构建。

相关推荐
jyan_敬言11 分钟前
【C++】string类(二)相关接口介绍及其使用
android·开发语言·c++·青少年编程·visual studio
liulilittle34 分钟前
SNIProxy 轻量级匿名CDN代理架构与实现
开发语言·网络·c++·网关·架构·cdn·通信
喷火龙8号38 分钟前
深入理解MSC架构:现代前后端分离项目的最佳实践
后端·架构
tan77º1 小时前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
Codebee1 小时前
“自举开发“范式:OneCode如何用低代码重构自身工具链
java·人工智能·架构
掘金-我是哪吒2 小时前
分布式微服务系统架构第158集:JavaPlus技术文档平台日更-JVM基础知识
jvm·分布式·微服务·架构·系统架构
JohnYan2 小时前
模板+数据的文档生成技术方案设计和实现
javascript·后端·架构
GiraKoo2 小时前
【GiraKoo】C++14的新特性
c++
悠悠小茉莉2 小时前
Win11 安装 Visual Studio(保姆教程 - 更新至2025.07)
c++·ide·vscode·python·visualstudio·visual studio
Da_秀2 小时前
软件工程中耦合度
开发语言·后端·架构·软件工程