热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SQLite架构

本文译自《ArchitectureofSQLite》介绍这篇文档描述了SQLite库的架构。如果想理解SQLite内部原理,或者对它进行修改,这篇文档提供了有帮助的信息。下图展示了

本文译自《Architecture of SQLite》

介绍

这篇文档描述了SQLite库的架构。如果想理解SQLite内部原理,或者对它进行修改,这篇文档提供了有帮助的信息。

下图展示了SQLite的主要组件和它们的协作方式。后文解释了这些组件的具体职责。

《SQLite架构》 SQLite模块

本文中各组件的原文译文对照:

原文译文
Interface接口
SQL Command ProcessorSQL命令处理器
Virtual Machine虚拟机
Tokenizer词法分析器
Parser语法分析器
B-TreeB树
Pager页缓存
OS InterfaceOS接口
Utilities通用库
Test Code测试代码

概览

SQLite的工作流程是将SQL文本编译成字节码,然后在虚拟机上运行这些字节码。

sqlite3_prepare_v2()和相关的接口起到编译器的作用,将SQL文本转化为字节码。sqlite3_stmt对象是一个字节码容器,存储了单条SQL语句所编译出的字节码。sqlite3_step()接口将字节码程序传给虚拟机,执行字节码程序直到它完成、返回结果集、遇到严重错误或被中断(interrupted)。

接口

C语言接口主要在main.clegacy.cvdbeapi.c中,也有一些接口分散在其他文件中,这是为了使它们能使用一些文件私有的数据结构。sqlite3_get_table()例程在table.c中,sqlite3_mprintf()在printf.c中,sqlite3_complete()在tokenize.c中,TCL Interface在tclsqlite.c中。

为避免名称冲突,SQLite库中的所有外部符号都以前缀sqlite3开头。那些用于外部使用的符号,也就是出现在SQLite API中的符号,会添加一个下划线,从而以sqlite3_开头。扩展API有时会在下划线之前添加扩展名,例如:sqlite3rbu_或sqlite3session_。

词法分析器

当一条SQL语句要被编译时,它首先被发送给词法分析器。

词法分析器将SQL文本分解成词,然后将它一个个交给语法分析器。词法分析器的文件是tokenize.c,其中的代码是手工写的。

注意此处的设计,是词法分析器调用语法分析器。熟悉YACC或者BISON的人可能习惯于反过来——让语法分析器调用词法分析器。前者更好,因为它可以做到线程安全,并且运行地更快。

语法分析器

语法分析器根据词的上下文赋予它语义。

SQLite的语法分析器通过Lemon LALR(1)生成。Lemon的功能和YACC、BISON类似,但是它所使用的输入语法更不容易出错。同时Lemon生成的语法分析器是可重入和线程安全的。Lemon定义了“非终结符析构器(non-terminal destructor)”的概念,因此它在遇到语法错误时不会泄露内存。Lemon所需的语法文件是parse.y,其中定义了SQLite使用的SQL语法。

因为Lemon很可能不在开发机器上,它完整的源代码在SQLite的tool文件夹中,仅有一个C文件。

代码生成器

语法分析器将词转化为语法树,代码生成器分析语法树,并且生成符合SQL功能的字节码。

prepared statement对象是这段字节码的容器。代码生成器包含很多文件:attach.c,** auth.cbuild.cdelete.cexpr.cinsert.cpragma.cselect.ctrigger.cupdate.cvacuum.cwhere.cwherecode.c以及whereexpr.c**。SQLite的魔法大多发生在这些文件中。

expr.c处理表达式的代码生成,where.c处理SELECT,UPDATE,DELETE语句的WHERE子句的代码生成。attach.cdelete.cinsert.cselect.ctrigger.cupdate.c,和vacuum.c处理和文件名对应的SQL语句的代码生成,其中每个文件都需要调用expr.cwhere.c中的例程。其他所有的SQL语句都由build.c处理。auth.c*实现了sqlite3_set_authorizer()的功能。

代码生成器,特别是where.cselect.c中的逻辑部分,有时被称作查询计划器query planner。对于任何一条SQL语句,可能有成百上千种不同的算法能得出结果。查询计划器是一个AI,尽力从其中选出最好的算法。

字节码引擎

生成器输出的代码最终由虚拟机来执行。

虚拟机本身完全包含在单个文件中,即vdbe.c文件。vdbe.h头文件定义了其他SQLite库与虚拟机之间的接口,而vdbeInt.h定义了虚拟机私有的数据结构和接口。

剩下的多个vdbe.c文件是虚拟机的辅助代码。vdbeaux.c文件包含了虚拟机使用的通用库,以及其他库用来构造VM程序的接口模块。vdbeapi.c文件包含了虚拟机的外部接口,比如sqlite3_bind_int()和 sqlite3_step()。单个值(字符串,整数,浮点数,二进制数据)存储在一个内部对象“Mem”中,该对象在vdbemem.c*实现。

SQLite通过回调C语言来实现SQL的函数。甚至内置的SQL函数也通过这种方式实现。大部分内置SQL函数,例如abs(), count(),substr()等,都写在func.c文件中。日期时间转换函数写在date.c中。一些函数,例如coalesce() 和 typeof()直接被代码生成器实现为字节码。

B树

SQLite使用B树结构来维护磁盘上的数据,B树的实现在btree.c文件中。

数据库中每个表和索引都使用单独的B树。全部的B树都存储在同一个磁盘文件中。文件格式的规格是明确且稳定的,并且保证向前兼容。

B树子系统对其他SQLite库的接口定义在头文件btree.h中。

页缓存

B树模块要求磁盘上的信息具有固定的页面大小。默认的页面大小(page_size)是4096字节,但是也可以设置为512到65536之间的2的整数幂。页缓存负责页面的读写和缓存。页缓存也提供回滚和原子性提交的抽象,并且负责对数据库文件加锁。

B树模块向页缓存请求页面,并且在修改页面,提交或回滚时通知页缓存。页缓存会处理大量的细节,以确保请求被快速,安全,高效地处理。

主要的页缓存实现是在pager.c文件中,WAL模式的逻辑在单独的wal.c中,内存型缓存实现在pcache.cpcache1.c文件中。页缓存子系统对其他SQLite库的接口定义在pager.h中。

OS接口

为了提供跨操作系统移植性,SQLite使用名为VFS的抽象对象。每个VFS提供对磁盘文件的打开、关闭以及读写方法,以及其他特定于操作系统的功能,如获得当前时间,为伪随机数生成器设置随机种子等。

SQLite目前对unix和Windows提供VFS,分别在os_unix.cos_win.c文件中。

通用类

内存分配,大小写不敏感的字符串比较例程,可移植的字符串到数字转换例程,以及其他通用库位于util.c中。

hash.c实现了哈希表结构,在语法解析器中被用作符号表。utf.c源文件包含Unicode转换的相关例程。在printf.c中,SQLite实现了自己私有的printf(),包含了一些拓展。在random.c中,SQLite也实现了自己的伪随机数生成器。

测试代码

在src文件夹中,以test开头的文件为测试代码,不被包含在标准库版本中。


推荐阅读
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • Opencv提供了几种分类器,例程里通过字符识别来进行说明的1、支持向量机(SVM):给定训练样本,支持向量机建立一个超平面作为决策平面,使得正例和反例之间的隔离边缘被最大化。函数原型:训练原型cv ... [详细]
  • Imdevelopinganappwhichneedstogetmusicfilebystreamingforplayinglive.我正在开发一个应用程序,需要通过流 ... [详细]
author-avatar
人民总动员
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有