深入理解SQLite:存储引擎、索引、事务与锁

news2024/11/25 16:42:08

文章目录

    • 一、存储引擎
    • 二、索引的数据结构和类型
      • 2.1 B-Tree
      • 2.2 其他类型的索引
      • 2.3 小结
    • 三、事务处理中的一致性问题
      • 3.1 脏读(Dirty Read)
      • 3.2 不可重复读(Non-repeatable Read)
      • 3.3 幻读(Phantom Read)
      • 3.4 小结
    • 四、事务隔离级别和MVCC实现
      • 4.1 串行化(SERIALIZABLE)
      • 4.2 可重复读(REPEATABLE READ)
      • 4.3 小结
    • 五、锁的类型和级别
      • 5.1 未锁定(UNLOCKED)
      • 5.2 共享(SHARED)
      • 5.3 保留(RESERVED)
      • 5.4 挂起(PENDING)
      • 5.5 排他(EXCLUSIVE)
      • 5.6 锁定级别的转换关系
    • 六、总结

SQLite是一款轻量级的数据库,广泛应用于各种软件和系统中。本文将深入探讨SQLite的存储引擎、索引、事务隔离级别、MVCC实现以及锁的类型和级别。

一、存储引擎

SQLite使用一种称为B-Tree的数据结构作为其存储引擎。B-Tree可以高效地插入、删除和查找数据,因此非常适合用作数据库的存储引擎。

二、索引的数据结构和类型

2.1 B-Tree

SQLite的索引也使用B-Tree数据结构。索引可以大大提高查询的速度,因为它可以让数据库快速找到满足查询条件的数据。B-Tree是一种自平衡的树结构,它可以保持数据有序,且在插入、删除和查找等操作中具有较高的效率。以下是为什么SQLite选择B-Tree作为索引数据结构的原因:

  1. 查询效率:B-Tree的查找效率非常高。在最坏情况下,B-Tree的查找时间复杂度为O(log N),其中N是存储在树中的键的数量。这意味着,即使索引中有大量数据,B-Tree也可以快速找到满足查询条件的数据。

  2. 插入和删除效率:B-Tree在插入和删除操作中也具有较高的效率。当插入或删除数据时,B-Tree可以自动调整其结构以保持平衡,并确保操作的时间复杂度为O(log N)。这使得B-Tree成为动态修改数据的理想选择。

  3. 有序存储:B-Tree可以保持数据有序,这意味着当执行范围查询或排序操作时,B-Tree可以直接返回有序的数据,无需额外的排序操作。

  4. 磁盘友好:B-Tree数据结构非常适合磁盘存储。由于B-Tree可以将相关数据存储在相邻的磁盘块中,因此可以减少磁盘I/O操作,从而提高查询性能。

由于上述优点,B-Tree成为了SQLite索引的理想数据结构。

2.2 其他类型的索引

B-Tree并非适用于所有场景。在某些特定情况下,SQLite还支持其他类型的索引,如:

  1. 全文索引(FTS):全文索引用于全文搜索,可以快速找到包含特定词汇的文本。SQLite使用一种称为虚拟表的特殊结构来实现全文索引。全文索引通常使用倒排索引(Inverted Index)数据结构来实现。

  2. R-Tree索引:R-Tree索引用于空间数据查询,可以快速找到满足特定空间条件的数据。R-Tree索引适用于处理多维数据,如地理位置数据、时间序列数据等。

2.3 小结

总之,SQLite选择B-Tree作为索引的数据结构,主要是因为它在查询效率、插入和删除效率、有序存储和磁盘友好性方面的优势。在特定场景下,SQLite还支持全文索引和R-Tree索引以满足不同的需求。但是索引并非总是有效的。在某些情况下,索引可能失效,例如查询条件使用了函数或表达式,或者查询条件不满足索引的列顺序。

三、事务处理中的一致性问题

脏读、不可重复读和幻读是数据库事务处理中常见的一致性问题。以下是它们的含义和出现场景:

3.1 脏读(Dirty Read)

脏读是指一个事务读取到了另一个事务尚未提交的数据。这可能导致数据不一致,因为读取到的数据可能会在未来被回滚。脏读通常出现在数据库的隔离级别设置为**“读未提交”**(Read Uncommitted)时。

场景:假设有两个并发事务A和B。事务A修改了一条记录,但尚未提交。此时,事务B读取了这条记录。如果事务A最后回滚了修改,那么事务B读取到的数据就是脏数据。

3.2 不可重复读(Non-repeatable Read)

不可重复读是指在同一个事务中,对同一数据的多次读取返回的结果不一致。这通常是因为在两次读取之间,另一个事务修改了该数据并提交。不可重复读主要出现在数据库的隔离级别设置为**“读已提交”**(Read Committed)时。

场景:假设有两个并发事务A和B。事务A首先读取了一条记录。此时,事务B修改了这条记录并提交。接着,事务A再次读取这条记录,发现数据已经发生了变化,导致不可重复读。

3.3 幻读(Phantom Read)

幻读是指在同一个事务中,对同一范围的数据进行查询时,返回的记录数不一致。这通常是因为在两次查询之间,另一个事务插入或删除了符合查询条件的记录并提交。幻读主要出现在数据库的隔离级别设置为**“可重复读”**(Repeatable Read)时。

场景:假设有两个并发事务A和B。事务A查询年龄在20-30岁之间的用户。此时,事务B插入了一条年龄为25岁的用户记录并提交。接着,事务A再次查询年龄在20-30岁之间的用户,发现记录数增加了,导致幻读。

3.4 小结

在这里插入图片描述

  • 在“读未提交”隔离级别下,可能发生脏读、不可重复读和幻读现象;
  • 在“读提交”隔离级别下,可能发生不可重复读和幻读现象,但是不可能发生脏读现象;
  • 在“可重复读”隔离级别下,可能发生幻读现象,但是不可能脏读和不可重复读现象;
  • 在“串行化”隔离级别下,脏读、不可重复读和幻读现象都不可能会发生。

为了解决这些一致性问题,数据库提供了不同的事务隔离级别。较高的隔离级别可以提供更好的一致性保证,但可能导致较低的并发性能。在实际应用中,需要根据数据一致性和并发性能的需求,选择合适的事务隔离级别。

四、事务隔离级别和MVCC实现

SQLite实际上只支持两种事务隔离级别:串行化(SERIALIZABLE)和可重复读(REPEATABLE READ)。然而,由于其底层的多版本并发控制(MVCC)实现,SQLite的可重复读隔离级别在某些情况下表现得类似于读已提交(READ COMMITTED)隔离级别。以下是SQLite事务隔离级别的详细解释。

4.1 串行化(SERIALIZABLE)

串行化是最严格的事务隔离级别。在串行化隔离级别下,事务按顺序一个接一个地执行,即每个事务在其他事务完成之后才能开始执行。这种隔离级别可以防止脏读、不可重复读和幻读等问题,但并发性能较低。

在SQLite中,串行化隔离级别通过在读取数据时获取共享锁(shared lock),在写入数据时获取排他锁(exclusive lock)来实现。在btree.c文件中,当一个事务开始时,SQLite会调用sqlite3BtreeBeginTrans函数获取一个共享锁(SHARED)。共享锁允许多个事务同时读取数据,但阻止其他事务写入数据。排他锁允许一个事务写入数据,但阻止其他事务读取或写入数据

4.2 可重复读(REPEATABLE READ)

可重复读隔离级别允许多个事务并发读取数据,但阻止其他事务在同一事务期间修改数据。这种隔离级别可以防止脏读和不可重复读,但可能导致幻读。

在SQLite中,可重复读隔离级别通过MVCC实现。在pager.c文件中,SQLite使用MVCC来管理多个并发事务。每个事务都有一个唯一的事务ID,用于标识事务的版本。

  • 当事务读取数据时,SQLite会调用pagerAcquire函数获取一个数据页面。这个函数会检查每个页面的版本,只返回事务ID小于或等于当前事务ID的版本。
  • 当事务写入数据时,SQLite会创建一个新的数据页面,并将其事务ID设置为当前事务ID。这样,每个事务都可以看到一个一致的数据快照,而不会被其他事务的更新干扰。

由于SQLite的MVCC实现,可重复读隔离级别在某些情况下表现得类似于读已提交隔离级别。这是因为当一个事务读取数据时,它实际上可以看到其他已提交事务的更新。然而,同一事务内的多次读取仍然是一致的,因为事务只能看到其开始时已经存在的数据版本。

请注意,SQLite不支持读未提交(READ UNCOMMITTED)隔离级别。读未提交隔离级别允许事务读取尚未提交的数据,可能导致脏读、不可重复读和幻读等问题。

4.3 小结

总结一下,SQLite通过MVCC实现了串行化和可重复读两种事务隔离级别。虽然可重复读隔离级别在某些情况下表现得类似于读已提交隔离级别,但它仍然可以提供一致的数据快照,防止脏读和不可重复读。

五、锁的类型和级别

SQLite使用一种基于磁盘文件的锁定机制,支持五种不同的锁定级别:未锁定(UNLOCKED)、共享(SHARED)、保留(RESERVED)、挂起(PENDING)和排他(EXCLUSIVE)。这些级别从低到高,每个级别的锁都可以阻止更高级别的锁,但不能阻止更低级别的锁。例如,共享锁可以阻止其他事务获取排他锁,但不能阻止其他事务获取共享锁。这些锁定级别在SQLite源码的sqlite3.h头文件中定义,具体实现在os_unix.c(Unix系统)和os_win.c(Windows系统)等文件中。

以下是这五种锁定级别的详细解释。

5.1 未锁定(UNLOCKED)

这是数据库的默认状态,表示没有任何事务正在访问数据库。在这种状态下,任何事务都可以获取共享锁或排他锁。

5.2 共享(SHARED)

在这种状态下,一个或多个事务可以同时读取数据库,但不能写入。当一个事务想要读取数据库时,它需要获取一个共享锁。如果当前没有排他锁或挂起锁,那么获取共享锁的请求将被允许。

5.3 保留(RESERVED)

在这种状态下,一个事务已经表示了写入数据库的意图,但还没有实际执行写入操作。只有一个事务可以持有保留锁,但其他事务仍然可以获取共享锁来读取数据库。当一个事务想要写入数据库时,它首先需要升级其共享锁到保留锁。

5.4 挂起(PENDING)

在这种状态下,一个事务正在等待写入数据库,但需要等待所有的共享锁释放。一旦所有的共享锁被释放,该事务将升级其保留锁到排他锁,并开始写入操作。在挂起状态下,不允许新的共享锁,但已经存在的共享锁可以继续存在直到完成。

5.5 排他(EXCLUSIVE)

在这种状态下,一个事务正在写入数据库。只有一个事务可以持有排他锁,而且在这个事务释放排他锁之前,其他事务不能获取共享锁或排他锁。只有在排他状态下,事务才能写入数据库。

5.6 锁定级别的转换关系

这些锁定级别的转换关系如下:

UNLOCKED -> SHARED -> RESERVED -> PENDING -> EXCLUSIVE

事务可以升级其锁定级别,但不能降级。例如,一个事务可以从共享锁升级到保留锁,但不能从保留锁降级到共享锁。当事务完成时,它需要释放其持有的所有锁,将数据库状态恢复到未锁定状态。

这种锁定机制使得SQLite能够支持多个并发读取事务,以及一个写入事务。通过合理地使用和管理这些锁,SQLite能够在保证数据一致性的同时,实现较高的并发性能。

六、总结

总的来说,SQLite是一款功能强大的轻量级数据库。了解SQLite的存储引擎、索引、事务和锁对于使用SQLite开发应用非常重要。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RVM安装Ruby笔记(Mac)

环境 硬件:Macbook Pro 系统:macOS 14.1 安装公钥 通过gpg安装公钥失败,报错如下: 换了几个公钥地址(hkp://subkeys.pgp.net,hkp://keys.gnupg.net,hkp://pgp.mit.edu),…

mac怎么删除python

mac 默认安装了python2;自己后面又安装了python3;为了方便,现在想将python3换成Anaconda3。 Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 Python3安装之后,在系统中不同目…

记录el-table的表格合并问题

项目需求背景: 利用el-table进行数据展示时,时常会有需要表格合并的情景,比如一个表格由5列组成: 类型 地区 金额 重量 长度 在这个表格里,如果同金额、重量的列可以合并到一起,这时应该怎么做呢&#xff1…

神经网络与深度学习(一)

线性回归 定义 利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法 要素 训练集(训练数据)输出数据拟合函数数据条目数 场景 预测价格(房屋、股票等)、预测住院时间&#…

计算机网络 - 基础篇总结

TCP/IP 网络模型有哪几层? 1.应用层 为用户提供应用功能 2.传输层 负责为应用层提供网络支持 使用TCP和UDP 当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏…

汇总:五个开源的Three.js项目

Three.js 是一个基于 WebGL 的 JavaScript 库,它提供了一套易于使用的 API 用来在浏览器中创建和显示 3D 图形。通过抽象和简化 WebGL 的复杂性,Three.js 使开发者无需深入了解 WebGL 的详细技术就能够轻松构建和渲染3D场景、模型、动画、粒子系统等。 T…

OSI七层参考模型

osi即开放系统互联参考模型。 osi的目的是为了解决主机间的通信 从下到上:物理层、数据链路层、网络层、传输层、会话层、表示出、应用层 上三层(应用层、表示出、会话层)负责产生数据,下四层(传输层、网络层、数据…

设计模式(9):外观模式

一.迪米特法则(最少知识原则) 一个软件实体应当尽可能少的与其他实体发生相互作用。 二.外观模式 为子系统提供统一的入口,封装子系统的复杂性,便于客户端调用。它的核心是什么呢,就是为我们的子系统提供一个统一的入口,封装子…

YOLOv5改进系列:升级版ResNet的新主干网络DenseNet

一、论文理论 论文地址:Densely Connected Convolutional Networks 1.理论思想 DenseNet最大化前后层信息交流,通过建立前面所有层与后面层的密集连接,实现了特征在通道维度上的复用,不但减缓了梯度消失的现象,也使其…

【前端Vue】Vue从0基础完整教程第4篇:面经PC端 - Element (下)【附代码文档】

Vue从0基础到大神学习完整教程完整教程(附代码资料)主要内容讲述:vue基本概念,vue-cli的使用,vue的插值表达式,{{ gaga }},{{ if (obj.age > 18 ) { } }},vue指令,综合…

Spring: 在SpringBoot项目中解决前端跨域问题

这里写目录标题 一、什么是跨域问题二、浏览器的同源策略三、SpringBoot项目中解决跨域问题的5种方式:使用CORS1、自定 web filter 实现跨域(全局跨域)2、重写 WebMvcConfigurer(全局跨域)3、 CorsFilter(全局跨域)4、使用CrossOrigin注解 (局部跨域) 一、什么是跨域…

稀碎从零算法笔记Day34-LeetCode:最小栈

感谢耶稣,笔者又过了一天“复活节”。月末斩杀一道Hard画上句号 题型:栈、模拟数据结构 链接:155. 最小栈 - 力扣(LeetCode) 来源:LeetCode 题目描述 设计一个支持 push ,pop ,…

适用于 Windows 的 6 个最佳视频转换器

视频转换器可以帮助您在设备上转换和播放不受支持的视频格式。它还可以方便地减小视频文件大小、以通用格式组织所有视频或与其他人共享文件以在不同设备上播放。 Windows 有大量视频转换器可供选择。虽然有些是免费的,但其他一些则提供迎合专业用户的高级功能。在…

Pycharm选择使用Anaconda环境中的Pytorch 失败解决办法之一

前几日想要复现一篇论文,结果给配的台式机完全禁不住,老是报溢出,慢都没事,溢出就很难受了,因此想用自己笔记本的GPU来训练。 安装以后遇到一个问题: Anaconda里创建了环境,安装好了对应pytor…

AR智能眼镜解决方案_MTK平台安卓主板硬件芯片方案开发

AR智能眼镜,是一个可以让现场作业更智能的综合管控设备。采用移动互联网、大数据和云计算等技术,现场数据的采集与分析;同时实现前端现场作业和后端管理的实时连动、信息的同步传输与存储。让前端现场作业更加智能,后端管理更加高…

再次加深理解Java中的并发编程

目录 一、线程、进程、程序 二、线程状态 三、线程的七大参数 四、lock与synchronized锁机制 一)、lock与synchronized锁区别 二)、synchronized锁原理 三)、Lock锁原理 五、synchronized锁升级原理 一)、锁升级基础知识 …

【Web】NSSCTF Round#20 Basic 两道0解题的赛后谈

目录 前言 baby-Codeigniter 组合拳! 前言 本想着说看看go的gin框架就睡了的,r3师傅提醒说赛题环境已经上了,那不赶紧研究下😀 主要来谈谈做题的心路历程 baby-Codeigniter 拿到题目的第一反应应该是:“什么是C…

C之易错注意点转义字符,sizeof,scanf,printf

目录 前言 一:转义字符 1.转义字符顾名思义就是转换原来意思的字符 2.常见的转义字符 1.特殊\b 2. 特殊\ddd和\xdd 3.转义字符常错点----计算字符串长度 注意 : 如果出现\890,\921这些的不是属于\ddd类型的,,不是一个字符…

SOA-面向服务架构

SOA-面向服务架构 1.概述2.SOA的设计原则包括:3. SOA实现方法1.Web Service2. 服务注册表3. 企业服务总线 细讲 超赞笔记 1.概述 SOA (Service-Oriented Architecture,SOA),从应用和原理的角度,目前有2种…

书生·浦语大模型-第一节课笔记

视频总结 23年发布的模型在一些材料中归位指令微调模型,后面逐渐升级应该已经是train的模型了 技术报告总结 InternLM2 Technical Report 评测与特点 6 dimensions and 30 benchmarks, long-context modeling, and open-ended subjective evaluations长文本…