首页 > 数据库 >SQLite数据库的工作原理

SQLite数据库的工作原理

时间:2023-06-15 11:03:42浏览次数:53  
标签:文件 SQLite int 数据库 原理 Btree 页面


介绍

数据库是构建软件系统的重要组成部分,用于有效地存储和读取数据。在这里,我们将使用早期版本的SQLite讨论数据库实现的一些体系结构细节。

SQLite是一个小型数据库应用程序,用于数百万个软件和设备。SQLite是由D.Richard Hipp于2000年8月发明的.SQLite是一个高性能,轻量级的关系数据库。如果您愿意在编码级别学习数据库的内部,那么SQLite是最好的开源数据库,具有高度可读的源代码和大量文档。阅读更高版本的SQLite变得有点困难,因为它包含许多新功能。为了理解数据库内部的基本实现,您应该对数据结构,计算理论以及操作系统的工作原理有一定的了解。

在这里,我们将研究SQLite 2.5.0版本。您可以在GitHub找到 SQLite后端的简单实现。 

为什么数据库

将数据保存在平面文件中并不能有效地读取和存储数据。数据库按正确顺序组织数据,以便数据读取和写入速度更快。数据可以是结构化的,半结构化的或非结构化的。数据库主要用于存储结构化和半结构化数据。可以根据要存储的数据结构的类型,按如下方式调度数据库。

  1. 关系数据库:常用的数据库类型,具有表结构。表可以与其他表有关系。用于处理此类数据库上的数据的SQL语言。
  2. 键值数据库:存储的数据以及与之关联的键。可以使用给定密钥检索数据。内存数据库通常被发现为这种类型的数据库。
  3. 对象数据库:数据结构更像是对象而不是表。
  4. 图形数据库:图形数据库是主要用于数据挖掘和社交媒体应用程序的节点和边缘的集合。

SQLite数据库架构

SQLite数据库体系结构分为两个不同的部分,分别命名为核心和后端。核心部分包含接口,令牌生成器,分析器,代码生成器和虚拟机,它们为数据库事务创建执行顺序。后端包含访问文件系统的B树,寻呼机和OS接口。Tokenizer,Parser和代码生成器共同命名为编译器,它生成一组在虚拟机上运行的操作码。

我从哪里开始?

要了解数据库的体系结构,您需要具备以下先决条件。

  1. 很好地理解数据结构和算法。特别是B树,链表,Hashmaps等数据结构。
  2. 对计算机体系结构有所了解 如何读写磁盘,分页和缓存如何工作。
  3. 理论计算机,如有限自动机和一些正则表达式知识。

SQLite架构

VFS(虚拟文件系统)

Unix和Windows上的文件访问权限彼此不同。VFS提供了访问文件的通用API,而不考虑其运行的操作系统的类型。此API包括打开,读取,写入和关闭文件的功能。以下是VFS中用于读取,将数据写入文件的一些API。

/ * 
创建文件连接以进行读写 
zFilename:文件名 
id:文件指针 
pReadonly:读或写 
* /
int  sqliteOsOpenReadWrite(const  char  * zFilename,OsFile  * id,int  * pReadonly);
/ * 
获取锁定以读取文件。这个功能应该是
在调用任何文件读取函数之前调用。 
如果成功则返回0
id:文件指针 
* /
int  sqliteOsReadLock(OsFile  * id);
/ * 
获取写锁定以写入文件。之前应调用此函数
对文件系统执行任何写入操作。
如果成功则返回0
id:文件指针
* /
int  sqliteOsWriteLock(OsFile  * id);
/ * 
移动到给定数量的offest以读取或写入文件
* /
int  sqliteOsSeek(OsFile  * id,int  offset);
/ * 
从sqliteOsSeek指向的偏移量中读取文件中的amt字节
* /
int  sqliteOsRead(OsFile  * id,void  * pBuf,int  amt);
/ * 
将ptf中的amt字节写入文件
* /
int  sqliteOsWrite(OsFile  * id,const  void  * pBuf,int  amt);

在这里,您可以使用sqliteOpenReadWrite函数开始使用文件。此函数为您提供指向文件的指针,该文件可用于向其读取或写入数据。接下来,应在执行任何读写操作之前获取锁。如果它只是一个读操作,则应获取读锁定。应该为读取和写入事务获取写锁定。 

然后可以通过将文件的偏移量提供到sqliteOsSeek函数中来寻找位置来完成读写操作。偏移量是从文件起始点到数据应写入或读取的位置的字节数。

呼叫器

页面是文件系统上数据库事务的最小单位。当数据库需要从文件中读取数据时,它会将其作为页面请求。将页面加载到数据库引擎后,如果页面在其缓存上频繁访问,则可以存储该页面。页面编号并从一开始。第一页称为根页面。页面的大小是不变的。

/ *
打开具有给定文件名的寻呼机
* /
int  sqlitepager_open(Pager  ** ppPager,const  char  * zFilename,int  nPage,int  nEx);
/ *
获取页码指定的页面
* /
int  sqlitepager_get(Pager  * pPager,Pgno  pgno,void  ** ppPage);
/ *
开始将数据写入pData中指定的页面
* /
int  sqlitepager_write(void  * pData);
/ *
将页面更改提交到文件中
* /
int  sqlitepager_commit(Pager *);
/ *
关闭与文件的连接
* /
int  sqlitepager_close(Pager  * pPager);

B树

Btree是一种数据结构,用于根据数据的值将数据存储为树。最简单的BTree形式是二叉树。数据库使用Btree数据结构来存储索引以提高数据库的性能。Btree的每个节点都包含一个用于索引的键列表。可以为表中的每个列创建Btree索引。每个Btree都有根页面,这是任何Btree搜索的起点。

要在Btree上指向一行,使用称为“Cursor”的特殊指针。光标用于指向以页面ID和偏移量idx给出的记录。SQLite在表上存储数据库模式,称为“master_table”。master_table始终存储在数据库的第一页上。 

/ *
打开与zFileName指定的页面文件名的文件连接 
nCache大小缓存
* /
INT  sqliteBtreeOpen(常量 字符 * zFilename,INT  模式,诠释 的nCache,B树 ** ppBtree)
/ *
开始交易。在任何btree修改之前应该调用此函数
操作
* /
INT  sqliteBtreeBeginTrans(B树 * PBT)
/ *
插入带有nKey字节的键pKey和带有nData字节的值pData 
进入Btree
* /
int  sqliteBtreeInsert(BtCursor  * pCur,const  void  * pKey,int  nKey,
                      const  void  * pData,int  nData)
/ *
将数据写入文件
* /
INT  sqliteBtreeCommit(B树 * PBT)
/ *
使用nKey字节将光标移动到匹配的pKey
* /
int  sqliteBtreeMoveto(BtCursor  * pCur,const  void  * pKey,int  nKey,int  * pRes)

VDBE(虚拟数据库引擎)

VDBE是一个运行一组操作的虚拟机,由代码生成器生成。所有SQL命令(包括insert,delete,update,select)都转换为一组操作码,然后在虚拟机上运行。每个操作码包含三个输入,命名为p1,p2和p3。您可以将此输入视为函数的输入。

下面我为以下SQL select语句添加了示例执行操作码堆栈。PC是程序计数器的指令ID。 SQLite中最有趣的事情是我可以通过在SQL查询开头附加“explain”关键字来查看给定SQL代码的VBDE操作码指令集。

解释select * from foo where value =“value”;

个人计算机

操作码

P1

P2

P3

评论

1

列数

1

0

 

将列数设置为1

2

的ColumnName

0

0


将列名设置为“值”

3

打开

0

3

FOO

打开游标并将其指向第三页,这是foo表的根页(p3并不重要

4

VerifyCookies

46

0

 

确保架构未更改


倒带

0

11

 

将光标移动到第一个条目

6


0

0

 

从Btree有效负载读取数据并将其放入堆栈

7


0

0

 

 

8

NE

1

10

 

弹出堆栈中的前两个元素。如果它们不相等,则跳转到指令P2。否则,继续执行下一条指令。

9

打回来

1

0

 

Pop P1从堆栈中取出并将它们组成一个数组。这将是此SQL表达式的结果行

10

下一个

0


 

将光标移动到下一条记录,如果数据退出转到P2,则转到下一行

11


0

0

 

关闭光标

编译器

Tokenizer,Parser和Code Generator在一起称为Compiler,它生成在VBDE上运行的操作码集。Tokenizer通过扫描SQL代码生成一组令牌。然后,它验证语法并生成解析树。代码生成器将此解析树转换为使用SQLite操作码编写的迷你程序。

结论

SQLite是一个简单,轻量级,高性能的关系数据库,广泛用于软件设计。Eite版本的SQLite是用简单的架构和高度可读的代码编写的。寻呼机提供了一个抽象层,可以将数据作为固定大小的块读写到文件系统中。而Btree提供了一种以内存方式存储数据的方法,可以更快地访问数据。当SQL进入SQLite时,它将SQL转换为SQLite机器代码并在VBDE上运行它。结果通过API发回给用户。

标签:文件,SQLite,int,数据库,原理,Btree,页面
From: https://blog.51cto.com/u_16145034/6485351

相关文章

  • MySQL数据库运维实录--通过MySQL Shell Dump/Load 实现数据库对象的逻辑备份与恢复
    [mysql@node01~]$mysqlshMySQLJS>\connectroot@node01:3306MySQLnode01:3306sslJS>util.dumpInstance('/home/mysql/backup')[mysql@node01~]$scp-rbackup/*node02:/home/mysql/backup/util.dumpInstance的关键特性1,多线程备份。并发线程数由thr......
  • 修复 Sqlite "database disk image is malformed"
    Sqlite是用于移动设备的轻量级数据库。Android编译遇到出错异常:databasediskimageismalformed 处理方法为通过对sqlite提供的修复命令建立脚本封装自动处理。修复方法来自网络搜索,年代久远,出处不可考,如找到出处,本文引用改为链接。 1#1.dumpSQL语句2def__d......
  • 顶奢好文:3W字,穿透Spring事务原理、源码,至少读10遍
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • SQLite3中自增主键归零方法
    SQLite3中自增主键归零方法Sqlite3记录被清除之后,如果表中有自增长字段,下次再插入数据,会继续延续之前自增长字段的历史记录。即使在清空table后,如果table中有自增ID值,那么这个值是不会归零的,而且会继续呈现递增。当SQLite数据库中包含自增列时,会自动建立一个名为sqlite_sequenc......
  • 在 Istio 服务网格内连接外部 MySQL 数据库
    为了方便理解,以Istio官方提供的Bookinfo应用示例为例,利用ratings服务外部MySQL数据库。Bookinfo应用的架构图如下:其中,包含四个单独的微服务:productpage:调用details和reviews两个服务,用来生成页面。details:包含了书籍的信息。reviews:包含了书籍相关的评论。它还......
  • JUC同步锁原理源码解析一 之ReentrantLock
    JUC同步锁原理1.锁的本质1.什么是锁?​ 通俗来讲,锁要保证的就是原子性,就是一个代码块不允许多线程同时执行,就是锁。从生活的角度上来说,就比如你要去上厕所,当你在上厕所期间,你会把门锁上,其他人只能排队。不允许多个人同时上厕所。2.锁的底层实现​ java语言是运行在jvm之上,jvm......
  • 彰显科创实力,巨杉数据库成功入选2022年粤港澳大湾区风投创投竞争力研究案例
    巨杉数据库凭借其卓越的技术和创新解决方案,入选2022年大湾区科创企业创新力TOP10,肯定了巨杉数据库在数据管理领域的成果以及市场影响力。日前,广东省风险投资促进会与南方财经全媒体集团,联合发布2022年粤港澳大湾区风投创投竞争力研究案例。粤港澳大湾区一直以来都是中国乃至全球......
  • 浅谈 thinkphp composer 扩展包加载原理
    浅谈thinkphpcomposer扩展包加载原理本文将介绍ThinkPHP中Composer扩展包的加载原理,帮助读者更好地理解和应用该功能。前言如题,今天感觉好久没有更新博客了。最近迷上了物联网开发。一直在研究stm32、51这些东西。想起来前几天群里面有人问到tp扩展包原理。其实这个前......
  • 对抗性自动编码器系列--有监督对抗自动编码器SAAE的原理及实现-随机数生成想要的数字
    文章目录前言监督对抗性自动编码器SAAE风格和内容的分离SAAE训练结果AEAAESAAE实验对比结果恢复效果对比从随机数重建图像的效果这部分实验代码前言先来看看实验:我们使用MNIST手写数字,测试通过自动编码器和对抗性自动编码器学习重建恢复效果。原始图像:自动编码器重建效果......
  • 对抗性自动编码器系列--自动编码器AutoEncoder的原理及实现-手写数字的重建
    文章目录前言自动编码器介绍自动编码器重建手写数字关于损失函数重建结果这部分实验代码前言先来看看实验:我们使用MNIST手写数字,测试通过自动编码器和对抗性自动编码器学习重建恢复效果。原始图像:自动编码器重建效果对抗性自动编码器重建效果虽然这里看到,自动编码器和对抗性自......