开源项目CuteSqlite开发笔记(二):SQLite的架构

在开发CuteSqlite图形客户端的时候,需要用到SQL的语法解释,来对SQL语句进行优化。找了很多的SQL语法解释器,都不是十分满意,只有翻开Sqlite的源码,看看SQLite对SQL语句的解释过程,本文是翻译的官方文档。

 官方介绍架构的文章:https://www.sqlite.org/arch.html

CuteSqlite源码:https://github.com/shinehanx/CuteSqlite.git

SQLite使用的Lemon解释器翻译文章:开源项目CuteSqlite开发笔记(三):SQLite使用的Lemon解释器

SQLite的架构

SQLite的架构图

Introduction 介绍

本文档描述了SQLite库的架构。这里的信息对于那些想要理解或修改SQLite内部工作原理的人很有用。

Overview 概述

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

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

Interface  接口

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

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

Tokenizer 分词器

当一个包含SQL语句的字符串要被求值时,它首先被发送到标记器(tokenizer)。tokenizer将SQL文本分解为标记(Token),并将这些标记(Token)一个接一个地交给解析器。tokenizer在文件tokenize.c中手工编码。

注意,在这个设计中,标记器调用解析器。熟悉YACC和BISON的人可能习惯于用相反的方式来做事情--让解析器调用标记器。不过,让标记器调用解析器会更好,因为它可以是线程安全的,而且运行得更快。

Parser 解析器

解析器根据上下文为标记分配语义。SQLite的解析器使用Lemon解析生成器生成(包含解释SQL语法,并生成C语言代码)。Lemon的工作与YACC/BISON相同,但它使用了不同的输入语法,这更不容易出错。Lemon还生成了一个可重入和线程安全的解析器。Lemon定义了非终结符析构函数(non-terminal destructor)的概念,这样当遇到语法错误时它就不会泄漏内存。驱动Lemon并定义SQLite理解的SQL语言的语法文件位于src/parse.y中。

因为Lemon是一个通常在开发机器上找不到的程序,所以Lemon的完整源代码(只有一个C文件)包含在SQLite发行版的"tool"目录中。(稍后在WINDOWS上使用GCC编译出lemon.exe,并解释src/parse.y成C语言代码)

Code Generator 代码生成器

在解析器将标记组装到解析树中之后,代码生成器运行以分析解析树并生成执行SQL语句的工作的字节码。准备好的语句对象是这个字节码的容器。代码生成器中有许多文件,包括:attach.c、auth.c、build.c、delete.c、expr.c、insert.c、pragma.c、select.c、deliver.c、update.c、vacuum.c、where.c、wherecode.c和whereexpr.c。在这些文件中,大多数严重的魔术发生。expr.c处理表达式的代码生成。where*.c处理SELECT、UPDATE和NULL语句上的WHERE子句的代码生成。文件attach.c、delete.c、insert.c、select.c、update.c和vacuum.c处理具有相同名称的SQL语句的代码生成。(这些文件的每一部分会调用expr.c和where.c中的例程。)所有其他SQL语句都是从build.c中编写的。auth.c文件实现了sqlite3_set_authorizer()的功能。

Bytecode Engine  字节码引擎

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

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

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

B-Tree b树

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

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

Page Cache 页面高速缓存

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

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

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

OS Interface OS接口

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

Utilities 公共的工具函数

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

Test Code 测试代码

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

上一篇:开源项目CuteSqlite开发笔记(一) 

下一篇:开源项目CuteSqlite开发笔记(三):SQLite使用的Lemon解释器 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/258099.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑气电联合需求响应的气电综合能源配网系统协调优化运行》

这个标题涉及到一个涉及气体(天然气)和电力的综合能源配网系统,并且强调了考虑气电联合需求响应的协调优化运行。让我们逐步解读: 气电综合能源配网系统: 这指的是一个结合了气体(通常是天然气)…

柔性数组详解

目录 一、柔性数组的特点:​ 二、使用sizeof计算包含柔性数组的结构体的大小 三、柔性数组的使用 代码1: 四、用结构体指针代替柔性数组 代码2: 五、柔性数组与结构体指针对比 • 在结构体中 • 最后一个成员 • 未知大小的数组 这就是柔性…

吴恩达《机器学习》12-1:优化目标

在机器学习的旅程中,我们已经接触了多种学习算法。在监督学习中,选择使用算法 A 还是算法 B 的重要性逐渐减弱,而更关键的是如何在应用这些算法时优化目标。这包括设计特征、选择正则化参数等因素,这些在不同水平的实践者之间可能…

代码随想录算法训练营第三十八天|完全背包,518. 零钱兑换 II ,377. 组合总和 Ⅳ

完全背包 例题:有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。 区别&#x…

机器学习硬件十年:性能变迁与趋势

本文分析了机器学习硬件性能的最新趋势,重点关注不同GPU和加速器的计算性能、内存、互连带宽、性价比和能效等指标。这篇分析旨在提供关于ML硬件能力及其瓶颈的全面视图。本文作者来自调研机构Epoch,致力于研究AI发展轨迹与治理的关键问题和趋势。 &…

小红书蒲公英平台开通后,有哪些注意的地方,以及如何进行报价?

今天来给大家聊聊当小红书账号过1000粉后,开通蒲公英需要注意的事项。 蒲公英平台是小红书APP中的一个专为内容创作者设计的平台。它为品牌和创作者提供了一个完整的服务流程,包括内容的创作、推广、互动以及转换等多个方面。 2.蒲公英平台的主要功能 &…

第一启富金:新添澳大利亚(ASIC)牌照

第一启富金:澳大利亞證券及投資委員會(ASIC) GOLDWELL GLOBAL PTY LTD 是 WHOLESALE INVESTOR SERVICES PTY LTD(CAR 編號 001304943)的企業授權代表開發澳大利亞客戶,WHOLESALE INVESTOR SERVICES PTY LT…

前端学习系列之CSS

目录 CSS 简介 发展史 优势 基本语法 引用方式 内部样式 行内样式 外部样式 选择器 id选择器 class选择器 标签选择器 子代选择器 后代选择器 相邻兄弟选择器 后续兄弟选择器 交集选择器 并集选择器 通配符选择器 伪类选择器 属性选择器 CSS基本属性 优…

Java_LinkedList链表详解

目录 前言 ArrayList的缺陷 链表 链表的概念及结构 链表的种类 1.单向或双向 2.带头或不带头 3.循环或不循环 LinkedList的使用 什么是LinkedList LinkedList的使用 LinkedList的构造 LinkedList的其他常用方法介绍 LinkedList的遍历 ArrayList和LinkedList的…

深入了解Java 8日期时间新玩法之Year、YearMonth、MonthDay、DayOfWeek

推荐语 在这篇文章中,我们将深入探讨Java 8中Year、YearMonth、MonthDay和DayOfWeek类的功能和使用方法。这些类是在Java 8中引入的新的日期时间API的一部分,它们为我们提供了更灵活、更易用的日期和时间处理能力。 尽管这些类在Java 8中已经出现&…

跨境电商系统搭建 无货源系统对接API 反向代购系统

跨境电商系统是为国外的客户代购中国商品的系统,系统实现与国内电商API对接,客户可直接在系统中搜索国内电商平台的商品。查看演示网站 一级功能二级功能 标准版 高级版 企业版 企业旗舰版 大客户尊享版 标准版高级版企业版企业旗舰版大客户尊享版 前台主…

泽攸科技二维材料转移台的应用场景及优势

随着二维材料的广泛研究和各种潜在应用的开发,对于二维材料样品的精密操控与转移的需求日益增加。特别是一些新型二维材料的制备和器件集成制备中,需要在显微镜下对样品进行观察与定位,并能够在微米甚至纳米量级上精确移動和转移样品。 传统…