[深度好文]10张图带你轻松理解关系型数据库系统的工作原理

news2024/12/23 2:42:02

[深度好文]10张图带你轻松理解关系型数据库系统的工作原理

原文(欢迎关注):https://mp.weixin.qq.com/s/CNCfWRpv8QlICGvZkLG4Jw

尽管数据库在我们应用程序中扮演着储存几乎所有状态的关键角色,但人们对其运行原理的了解通常仅停留在较为浅显的层面,而数据库的高效稳定运行又是大多数应用系统基础性的保障。

因此,在本篇文章中,在不深入讨论数据库特有的细节问题的前提下,我将全面介绍你应当理解的关于关系型数据库索引的相关内容。此外,我将简洁明了地探讨事务和隔离级别,以及它们如何影响你对具体事务的思考和理解。

关系型数据库

什么是索引

索引是一种帮助减少数据查询时间的数据结构。索引在实现这一目标时,需要付出存储、内存和保持更新(较慢的写入速度)的额外成本,这使得我们可以跳过检查每一行表的繁琐任务。

就像书后面的索引页一样,它可以帮助你找到正确的一页。

书后面的索引页

为什么需要索引

小量的数据是易于管理的(比如一个小班级的出勤表), 但是, 当数据规模变得更大时(比如一个大城市的出生登记), 事情就不那么容易了。之前能够很快执行的操作都开始变得缓慢。

想象一下,如果你需要在一页 A4 纸的名单上上找到某个信息,与需要在上千页的名单中找到它,你的查询策略会有何变化。

无论你想到的查询策略是什么,几乎总会有某个数据库在某个特定的时间点用到了和你相似的策略,因为随着它们的发展,他们需要收集和存储的数据会逐渐变得庞大,最终必将遇到上述的问题。

因此,我们需要索引来帮助我们尽可能快地获得我们需要的相关数据。

索引是如何工作的?

一般而言,索引越多读取性能越好,但这是以写性能的降低为代价的,因为你需要保持对索引的更新

其中一个方案是根据查询方式来维护数据存储逻辑。比如你需要通过姓名来查询某个名单,那就将名单按照姓名进行排序。但这个策略有许多问题需要考虑:

  1. 如果我有多种查询方式呢? 比如,既有用姓名查询也有用身份证查询。
  2. 如果有新数据的写入, 写入速度会受到多大的影响?
  3. 如何处理数据的更新呢?
  4. 所有的数据操作的复杂度是什么样的呢?

无论你的原始策略是什么,肯定都需要一种维护数据顺序的方式以便获取相关的无序数据。

如下表中的例子,几乎不需要什么时间,我们就可以通过扫描整个表将查询到我们想要的数据。

+─────+─────────+──────────────+
| id  | name    | city         |
+─────+─────────+──────────────+
| 1   | Mahdi   | Ottawa       |
| 2   | Elon    | Mars         |
| 3   | Jeff    | Orbit        |
| 4   | Klay    | Oakland      |
| 5   | Lebron  | Los Angeles  |
+─────+─────────+──────────────+

加入存储的数据规模无法全部存放到内存,或者需要很长的时间才能将数据从磁盘加载到内存呢?如下表中,数据分散在磁盘中,无法完全加载到内存。

+──────────+─────────+───────────────────+
| id       | name    | city              |
+──────────+─────────+───────────────────+
| 1        | Mahdi   | Ottawa            |
| 2        | Elon    | Mars              |
| 3        | Jeff    | Orbit             |
| 4        | Klay    | Oakland           |
| 5        | Lebron  | Los Angeles       |
| ...      | ...     | ...               |
| 1000000  | Steph   | San Francisco     |
| 1001000  | Linus   | Portland          |
+───────+─────────+──────────────────────+

大部分 R&D 立刻想到了,我们需要字典(hash表)以及一种可以不需要扫描磁盘直接定位到正在查询的指定行的手段。

索引叶子节点提供指定列到索引的映射,它能够存储符合条件的行所在的位置。

RowIDs indexes mapping to table data

这些索引叶子节点是索引列和相应行在磁盘上的位置之间的映射。它提供了一种通过索引列来快速获取指定行的方法。扫描索引的速度会更快,因为它是你要搜索的列的紧凑表示(更少的字节)。它为你节省了读取一堆块来寻找所需数据的时间,而且更便于缓存,进一步加快了整个过程的速度。

这些索引的叶子节点是统一大小的,我们在每个块中尽可能多地存储这些叶子节点。由于这种结构需要对数据进行排序(逻辑上,而不是磁盘上的物理排序),我们需要解决必须快速添加和删除数据的问题。通常我们用一个双向链表来解决这个问题。

这里的好处有两个:它允许我们向前和向后读取索引叶子节点,并在我们删除或添加新行时快速重建索引结构,因为我们只是在修改指针。

由于这些叶子节点在磁盘上并不是按顺序排列的,我们需要一种方法来获得正确的索引叶子节点。

平衡树(B-Tree)

B树 VS B+树

B树 VS B+树

B+树主要区别是,不在中间节点存储任何数据。所有的数据引用都链接到叶子节点上,这样可以更好地缓存树状结构(中间节点数据规模小更便于缓存索引信息)。

其次,B+树叶子节点是链接的,所以如果你需要做索引扫描,你可以简单的线性遍历,而不是向上和向下遍历整个树,从磁盘上加载更多的索引数据。

在关系型数据库中,B+树的结构如下图:

数据库中的B+树

什么是事务

事务是数据库操作的基本单位,它要么完全成功要么完全失败,不可能存在部分成功部分失败的情况。

数据不一致

在不同数据隔离级别中可能会出现一些数据不一致现象,了解这些现象对于调试你的系统以及了解你的系统能够容忍什么样的不一致是至关重要的。

不可重复读(Non-repeatable reads)

不可重复读

如上图所示,如果你在事务中的两次后续读取之间不能获得一致的数据视图,就会发生不可重复的读取。在特定的模式下,数据库的并发操作可能会出现你刚读的值被修改,导致不可重复的读取。

脏读(Dirty reads)

脏读

类似地,当你执行了一次读取,另一个事务更新了同一行,但没有提交工作,你执行了另一次读取,你可以访问未提交的(脏)值(这不是一个持久的状态变化,与数据库的状态不一致), 就会发生脏读取。

幻读(Phantom reads)

幻读

幻象读取是另一种已提交的数据不一致现象,他常发生在处理数据统计的场景。例如,你在一个特定的事务中两次计算客户的总数。在两次连续的读取之间,另一个客户注册或删除了他们的账户(已提交),如果你的数据库不支持这些事务的范围锁,这将导致你得到两个不同的值。

隔离级别

SQL标准的四种隔离级别

SQL标准定义了4个标准隔离级别,这些级别可以而且应该被全局配置(如果我们不能可靠地知道隔离级别,就会发生一些奇怪的问题)。

可重复读(REPEATABLE READ)

在这个隔离级别下,确保在一个事务中多次读取同一数据时,得到的结果是一致的。

这意味着事务在开始时会创建一个一致的快照,然后在事务结束之前,其他事务对数据的修改不会影响该事务的读取结果。

在可重复读级别下,解决了不可重复读的问题,但可能出现幻读问题。

串行化(SERIALIZABLE)

这是最高的隔离级别,它确保事务之间的并发执行就像是顺序执行一样。

在这个级别下,事务串行执行,避免了脏读、不可重复读和幻读的问题。

虽然序列化提供了最高的数据一致性,但也牺牲了并发性能,因为事务必须依次执行,不能并行处理。

读提交(READ COMMITTED)

在这个隔离级别下,一个事务只能读取到已经提交的数据。这意味着脏读的问题被解决了,因为事务只能看到其他事务已经提交的数据。

然而,在这个级别下,可能会出现不可重复读问题。

读未提交

在这个隔离级别下,一个事务可以读取到另一个事务尚未提交的数据。这意味着一个事务可能会读取到脏数据(未经提交的数据),即脏读。

这个级别提供了最低的隔离性,允许并发事务之间产生相互干扰。

本文翻译编辑自:
https://architecturenotes.co/things-you-should-know-about-databases/

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

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

相关文章

跟我一起使用 compose 做一个跨平台的黑白棋游戏(4)移植到compose-jb实现跨平台

前言 在上一篇文章中,我们已经实现了游戏的所有界面和逻辑代码,并且在 Android 上已经可以正常运行。 这篇文章我们将讲解如何将其从使用 jetpack compose 修改为使用 compose-jb 从而实现跨平台。 老规矩,先看效果图: 可以看到…

063:cesium设置带边界线材质(material-7)

第063个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中设置带边界折线材质,请参考源代码,了解PolylineOutlineMaterialProperty的应用。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共89行)相关API参考…

Python-matplotlib中的pie(饼)图

Python-matplotlib中的pie(饼)图 %matplotlib inline import matplotlib.pyplot as pltm 51212 f 40742 m_perc m/(mf) f_perc f/(mf)colors [navy,lightcoral] labels ["Male","Female"]plt.figure(figsize(8,8)) paches,te…

为什么不胜任的人,反而获得晋升?

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID:jishulingdaoli) 也许你有过这样的经历,自己勤勤恳恳地干活,每个月却只拿着微薄的薪水,有些人明明无法胜任工作,却像坐了火箭一样飞速晋升。这种现象在现实生活中无处不在…

3699元还配同价位最好屏幕!Redmi Book 14评测:几乎完美的“水桶”轻薄本

一、前言:4K价位最好屏幕 不久前,有网友让我推荐一台4000元价位的轻薄本,笔者直接选了一台搭载i5-13500H处理器且价格仅售4299元的某一线品牌产品。 但是,事后才发现不对,因为这款极具性价比的笔记本竟然用了45%NTSC色…

MIT6.824 lecture5上课笔记(涉及到Lab2A)- Go threads and raft

总结:本节课讲解了一些会在lab2中使用到的go的多线程技巧,会给一些简单的demo,lab2中可能会借鉴这些demo。 详细的Lab2 raft算法实现源码,请参考我的个人仓库(记得点颗星星), 配合readme食用更佳。 MIT6.…

ChatGPT 使用 拓展资料:如何善用大语言模型的推理能力?

ChatGPT 使用 拓展资料:如何善用大语言模型的推理能力?

ChatGPT Plus 会员续费扣款失败如何处理

扣款失败 笔者由于开通 ChatGPT Plus 会员比较早,3月26日一个月就到期了,但是最近几天注意到,虚拟卡上也没有提醒我扣费,还是能继续使用 GPT-4.0,就很奇怪,于是就研究了一番。 PS: 如果有小伙伴还不会开通 …

python 文件操作 , 异常处理 , 模块和包

文件操作 1.写数据 # open(name, mode) # name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。 # mode:设置打开文件的模式(访问模式):只读、写入、追加等。 #1.打开文件---通道建立--申请资源 # w 模式会清空之前的内…

【三维激光扫描】实验04:SiScan基于点云的量测功能

SiScan软件提供的基于点云的量测功能有:两点距离量测、多点距离量测、点到面距离量测、高度量测、坡度量测、角度量测、投影面积量测等等。 文章目录 一、两点距离量测二、多点距离量测三、点到面距离量测四、高度量测五、坡度量测六、角度量测七、投影面积量测一、两点距离量…

分布式与并行计算—并向算法实现

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 原始串行快速排序算法中有“分而治之”的递归调用部分,在每次选择pivoit并把序列按照小于pivoIt和大于pivoit分成两类后,左右两部分的递归排序可以并发执行。 运行时间 为了减小偶然性因素造成的时间差…

postgresql|数据库|插件学习(一)---postgresql-12的内置插件pg_stat_statements的启用和使用

前言: 插件就是原软件的扩展功能。postgresql有非常多的各种各样的插件,当然了,插件不安装对于我们使用数据库并没有什么太多的影响,可能只是不舒服一些而已,但有一些插件我们如果有安装,那么,对…

【NMI 2021】从生物学角度看进化计算(6个生物进化特征)

A biological perspective on evolutionary computation “生物学视角下的进化计算”,总结了进化算法——通过对比模拟和真实的进化,指出当前进化算法与生物进化存在的六点差异,并指出了对应的改进方案。 何为进化算法? 将任意问…

第二部分——长难句——第二章——复合句——第二节——状语从句

最后一类了哦 一,状语从句的概述 (一)状语从句的含义 一个句子作状语表达描述性的信息 一个主句可以组合好几个状语从句,因为可以表述不同方面的信息。 (二)状语从句的写法 状语从句的连接词叫做从属连…

Java--内部类学习笔记

本文介绍了什么是内部类,Java中的内部类:实例内部类. 静态内部类.局部内部类.匿名内部类的语法和注意事项,以及每个内部类的运用场景,以及简单介绍了匿名内部类更简洁更特殊的语法->lambda表达式 Java内部类学习笔记 一.什么是内部类?二. 内部类的分类1.实例内部类2.静态内…

【计算机视觉 | 扩散模型】新论文 | DragGAN论文:如果甲方想把大象 P 转身,你只需要拖动 GAN 就好了

文章目录 一、论文说明二、前言三、论文理解四、实验4.1 定性评估4.2 定量评估4.3 讨论 一、论文说明 2023年5月18日提交的论文,华人一作。 论文地址: https://arxiv.org/pdf/2305.10973.pdf项目地址: https://vcai.mpi-inf.mpg.de/projec…

pg事务:子事务

什么是子事务? 一般事务只能整体提交或回滚,而子事务允许部分事务回滚。 SAVEPOINT p1 在事务里面打上保存点标记。不能直接提交子事务,子事务也是通过事务的提交而提交。不过可以通过ROLLBACK TO SAVEPOINT p1回滚到该保存点。 子事务在大…

人工智能基础部分19-强化学习的原理和简单应用,一看就懂

大家好,我是微学AI,今天给大家介绍一下人工智能基础部分19-强化学习的原理和简单应用,随着人工智能的不断发展,各种新兴技术不断涌现。作为人工智能的一个重要分支,强化学习近年来受到了广泛关注。本文将介绍强化学习的…

基于C++的物资管理系统的设计与实现

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 一 需求分析 程序需实现以下功能: 新物资信息录入(编号、名称、库存) 查询已录入的所有物资信息(编号或名称为索引) 添加物资信息(编号或名称为索引&…