【数据库】索引与事务

news2024/11/26 15:00:54

目录

1、索引

1.1、概念

1.2、索引的作用

1.3、 索引的缺点

1.4、数据库中实现索引的数据结构

1.4.1、B树/B-树

1.4.2、B+树 

 1.4.3、回表

1.5、使用场景

1.6、索引的使用 

1.6.1、查看索引

1.6.2、创建索引 

1.6.3、 删除索引

1.7、索引的分类

2、事务

2.1、为什么使用事务

2.2、事务的概念

2.3、回滚机制(rollback) 

 2.4、事务的使用

2.5、事务的特性

 2.6、事务的隔离级别

 2.6.1、MySQL中的四种事务隔离级别

2.7、脏读问题 

2.8、不可重复度问题

2.9、幻读问题


1、索引

索引的创建会占用一定的物理空间,索引值是存放在磁盘空间中的,但是为了减少IO访问次数,提高程序的效率,在访问数据的时候他会先从磁盘空间中预读一定长度的索引数据放在缓存中。

1.1、概念

在MySQL中,索引(index)也叫做键(key)

数据库的索引就是为了提高数据的查询速率的方法。数据库的索引类似于书籍的目录。在书籍中,目录允许用户不必翻阅整本书就能迅速找到所需要的信息。在数据库中同理,索引也允许数据库程序迅速的找到表中的数据,而不必扫描整个数据库。

1.2、索引的作用

  • 我们的数据库的数据是存储在硬盘中的,而查询数据的时候要从硬盘中读取数据。而在硬盘中读取数据相比于在内存中读取数据是慢了不止一个数量级。
  • 如果我们通过遍历在硬盘空间中查找数据,每查找一次数据都需要程序与硬盘进行一次交互(数据的交互,也就是硬盘的IO),而一段程序中最拖慢程序速度的就是硬盘的IO,可想而知程序的速度会非常慢。
  • 但是我们通过索引的方式来查找数据,我们将索引值存在内存空间中,通过查找内存空间的值,来找到索引所对应的表中的完整数据。这样就减少了程序与硬盘空间的交互(减少了硬盘的IO次数)。这样就提高了程序的效率。这就是我们常说的以空间换时间

1.3、 索引的缺点

  • 创建索引和维护索引需要耗费时间,这种时间随着数据量的增加而增加。
  • 需要付出额外的空间代价来保存索引数据
  • 当对表中的数据进行增加、删除和修改的时候,索引也会跟着改变,降低了数据的维护速度,也可以理解为拖慢了增加、删除和修改数据的速度。

1.4、数据库中实现索引的数据结构

  • 我们在数据结构中学习过二叉搜索树、红黑树、avl树和哈希表这样的数据结构,二叉搜索树在平衡的情况下,可以实现快速查找数据。哈希表可以更快的查找数据。
  • 哈希表查找的时间复杂度为O(1),二叉搜索树在树平衡的时候它的时间复杂度为书的高度。但是在最坏的情况下,它的时间复杂度为O(N).

上述说到的这些数据结构都不能作为数据库中实现索引的数据结构。

  • 二叉搜索树、avl树、红黑树。他们都是单个存储的,将一个完整的数据存入结点中,而数据库中完整的数据就是一张表中的一条记录。这样每个结点占用的空间就比较大,所以不能将这些结点存在内存中,就需要存入硬盘中,而每查找一个数据就需要一个结点一个结点的比对,每比对一次结点中的数据,就相当于在硬盘中进行了程序与硬盘的交互(也就是硬盘的IO) 。这样程序的效率就非常低。
  • 而哈希表是一个非常快速的查找数据的数据结构,但是它只能进行值相等的比较,但是像大于,小于这样的范围比较,还有模糊匹配,他都是不能实现的。

所以数据库使用的是B+树

1.4.1、B树/B-树

我们在学习B+树的时候,先来了解一下它的前身B树。

B树,也叫B-树,此处的(-),不是减号,而是一个连接符。

每个结点中存放一定量的数据表中的每行数据(id,name,score,....),当结点中达到了规定的元素个数是,采取调整,B树就可以解决树过高的问题也就是IO访问次数过多的问题。但是这个结构MySQL中没有采用,而是使用B+树作为数据库数据存储的一种结构。 

1.4.2、B+树 

 B+树的特点: 

  1. 一个结点,可以存储N个key,同时N个key划分出了N个区间。
  2. 每个结点中的key的值,都会在子节点中存在,同时该key是子节点的最大值
  3. B+树的叶子节点,是首位相连,类似于一个链表
  4. 由于叶子节点是一个完整的数据集合,所以只在叶子节点这里存储数据表中的每一行的数据,而非叶子结点只存储key值本身即可

B+树的优势:

  1. 当前一个结点保存更多的key,最终树的高度更矮。查询的时候减少了IO访问(这里指硬盘访问次数)次数(和B树相同)
  2. 所有的查询最终都会落在叶子节点上。(查询任何一个数据,经过的IO访问次数是一样的,因为叶子节点保存完整的数据) 。所以B+树的IO访问次数是更稳定的。这样就可以对程序的执行效率有一个跟稳定的评估。
  3. B+树的所有的叶子节点,构成了链表,此时比较方便进行范围查询。(比如查询学号5~11的同学)
  4. 由于数据都在叶子结点上,非叶子节点只存储key,导致非叶子结点占用空间是比较小的,这些非叶子结点就可能在内存中缓存(或者缓存一部分)。进一步减少了IO访问次数。

 1.4.3、回表

 ❓❓❓上述B+ 树这个结构,我们默认id是表的主键了。如果一个表中存在多个索引查询的时候该怎样查呢?针对id 有主键索引,name又存在一个索引。


❗❗❗表的数据还是按照id为主键,构建出B+树,通过叶子节点组织所有的数据行,其次,针对name这一列,会构建另外一个B+树。但是这个B+树的叶子结点就不再存储这一行的完整数据,而是存主键id。此时如果根据name来查询,查到叶子结点得到的只是主键id,还需要通过主键id去主键的B+树里再查一次。所以这里就需要查两次B+树了。这个操作就叫做回表

1.5、使用场景

要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点

  • 数据量较大,且经常对这些列进行条件查询
  • 该数据看表的插入操作,及对这些列的修改操作频率较低
  • 索引会占用额外的磁盘空间 

满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。 反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。

1.6、索引的使用 

1.6.1、查看索引

格式:

show index from 表名;

 查询学生表中额索引,学生表中并没有手动创建索引,我们再设置主键的时候,自带的索引。

 

1.6.2、创建索引 

对于非主键,非唯一约束、非外键的字段,可以创建普通索引(列名/字段名可以有多个,用逗号隔开,一个索引包含多个字段就叫做组合索引)

格式

create index 索引名 on 表名(列名);
create index 索引名 on 表名(列名1,列名2...);

 案例:我们基于name这一列创建一个普通索引。(相当于student表有基于name这一列创建出一个目录。)

create index  index_student_name on student(name);

 ❗❗❗创建索引时因注意的事项:

  • 当一个表已经创建好了,并且里面存在大量数据,这时候再根据表的某一列创建索引,这个操作有可能就很危险。表中的数据很大,建立索引的开销也就很大。可以想象一下有一本很厚的书,现在让你手动写一个目录出来,这个工作量就会很大。
  • 好的做法就是再创建表的时候,就设定好索引。
  • 如果表中存在很多数据了,索引就不要动了。

1.6.3、 删除索引

格式

drop index 索引名 on 表名;

 案例:删除student表中的index_student_name索引。

❗❗❗ 注意:删除索引也存在风险。

1.7、索引的分类

MySQL目前的主要索引类型有:普通索引,唯一索引,主键索引,组合索引,全文索引,聚簇索引,非聚簇索引等。

  1. 普通索引:就是在数据表的字段设立索引的时候,不需要添加任何额外的限制条件(唯一,非空等的限制),该类型的索引可以创建再任何数据类型的字段中。
  2. 唯一索引:在数据表中设立索引的时候,限制索引修饰的字段必须具有唯一性,根据这个唯一索引可以比普通索引更快的查询到数据库中的某条记录。
  3. 主键索引:当创建表的时设立了主键约束,这张表也就存在了索引。也就是主键索引,也叫做聚簇索引。
  4. 全文索引:主要是对字符串类型建立的索引,基于分词的索引,主要是基于char,varchar,text类型的字段上,以便于能够更快的查询到数据量较大的字符串类型字段。
  5. 聚簇索引:聚簇索引一般指的是主键索引(表中存在主键索引的情况下)。
  6. 非聚簇索引:非聚簇索引的叶子节点仍然是索引值。如上边说到的存在主键索引(id)的情况下,又创建了一个普通索引(针对name),我们根据name查找数据的时候,会在name对应的B+树的叶子节点处找到索引值,再去id的B+树中找数据。

 ❗❗❗注意:如果一张表中没有主键,MySQL会每一行记录生成一个唯一的字段,使用这个字段作为索引。


2、事务

2.1、为什么使用事务

1️⃣现在转账的操作已经很普遍了,这里有一个账户表(account表),第一个用户又1000元,第二个用户没有钱。

 2️⃣现在第一个用户个第二个用户转500元。这时候两步操作实现这个过程。

通过给2的账户加500,给1的账户减500实现。

update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;

假设,在执行转账这个操作的时候,第一步操作执行完成之后,数据库奔溃了或者主机宕机了。此时只执行了第一句代码,第二句代码还没有被执行。呈现的一个情况就是1用户的钱扣了,但是2的钱还没有到账。显然这种操作是不现实的。

要让这种情况不发生,就需要使用事务来控制,保证让这两个SQL要么全部执行,要么执行失败。

2.2、事务的概念

  • 本质就是把多个SQL语句打包成一个整体,要么全部执行成功,要么就一个都不执行,不会出现执行一半这样的中间状态。
  • 在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。

2.3、回滚机制(rollback) 

上面说到的,将多个SQL语句打包成一个整体,有么执行成功,要么不执行。这里的"不执行"并不是真的不执行,而是执行了,中间出了错误。选择了恢复现场,把数据还原到未执行之前的状态了。就像我们使用的Ctrl+Z 。我们把这个恢复数据的操作,称为"回滚"(rollback).事务的原子性就是通过回滚这个机制来保证的。

 ❓❓❓这里又存在一个问题,进行回滚的时候,咋知道回滚是要恢复到什么状态呢?

数据库中存在日志文件,他是专门用来记录事务的操作步骤的。这个日志文件是保存在硬盘空间的

 2.4、事务的使用

三步操作

  1. 开启事务:start transaction;
  2. 执行多条SQL语句
  3. 回滚或提交rollback/commit;

rollback即是全部失败,commit即是全部成功。

案例:

start transaction;//开启事务
//执行多条SQL语句
update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;
commit;//提交事务

2.5、事务的特性

1、原子性(Atomicity)【核心特点】

将多个SQL语句打包成一个整体,这样的操作就叫做事务的原子性。表示事务的不可分割的最小单位。事务的出现就是为了解决原子性的问题。

2.一致性

事务执行之前于执行之后,要保持正确的结果。就像银行转账一样,1用户少了五百,2用户相应的是多了500,而不能是多了5000.

3、持久性

事务修改的内容是写到硬盘上的,持久存在的。重启服务器也不会丢失。

4、隔离性

隔离性是为了解决"并发"执行事务,所引起的问题。确保多个事务执行的过程中不互相干扰。

 2.6、事务的隔离级别

MySQL服务器可以支持多个客户端的访问,如果多个客户端对多个数据表进行数据操作,不会产生问题,但是多个客户端对一个数据表中的数据进行操作。那么就会产生很多问题。这里就需要不同的隔离级别对可能出现的问题进行解决。

隔离级别越低,可以支持同时访问同一个数据表的客户端就越多,数据的安全性就越低;如果隔离级别越高,那么可以支持同时访问同一个数据表的客户端就越少,性能变低,数据安全性变高。

 2.6.1、MySQL中的四种事务隔离级别

  1. read uncommitted (读未提交):没有进行任何限制,并发高(效率最高),隔离性最低(准确性最低)(脏读,不可重复读、幻读的问题都有可能出现)
  2. read committed(读提交):给写加锁,并发程度降低,隔离性提高了(不可重复读和幻读可能出现)
  3. repeatable read (可重复读):给写和读都加锁,并发程度有降低了,隔离性有提高了(幻读的问题可能出现)
  4. serializable(串行化):并发程度最低,隔离性最高。

2.7、脏读问题 

一个事务A正在对数据进行修改的过程中,结果还没有提交之前,另外一个事务B,也对同一个数据进行了读取。读取的数据并不是提交后的数据。此时B的操作就成为"脏读",读到的数据也称为"脏数据"。这里的脏表示的意思是无效。

为什么说是无效的数据,事务A在对数据进行修改的时候,发生了回滚。那之前修改的数据,全都无效了。

❗❗❗解决脏读问题:给写操作加锁 

给写操作的事务A加上一把锁,在事务A开始进行写操作的时候加锁,事务提交或者回滚的时候释放锁,被锁的事务不能与其他事务共存,写锁也叫排他锁这样写操作读操作不能同时执行

 

 这个给写加锁的操作,就降低了并发程度(降低了效率),提高了隔离性(提高了数据的准确性)。

2.8、不可重复度问题

脏读问题被解决了,又出现了新的问题。有三个事务A,B,C,事务A读取数据,事务B,C对同一条数据进行修改。现在事务B对这条数据进行了修改,并且提交了,在执行事务A的时候,对这一条数据进行了读取。得到了数据B。然后事务C对数据进行了修改,并提交了,现在事务B在执行过程中,又需要读取这条数据,现在读取的数据为数据C。这时就意味着同一个事务A之内,多次读取数据,读出来的结果是不相同的,我们预期是一个事务中,多次读取的结果得是一致的。这就叫做"不可重复读"。

解决不可重复读问题:给读操作加锁。

在读的事务也加锁,但是这个锁是一把(共享锁),多个读锁可以共存,但是由于写锁是排他锁,所以读锁不能与写锁共存,也就是说,在加了读锁之后,不能进行写操作。

通过这个读加锁,有进一步的降低了事务的并发处理能力(处理效率也降低),提高了事务的隔离性(数据的准确性有提高了)。

2.9、幻读问题

当前已经进行了写加锁和读加锁。简单来说就是在写操作的时候不能进行其他操作,在读的时候,不能进行写操作。读加锁这时针对一条记录来说,在读的时候别的事务不能对这条记录进行修改,但是可以在这个数据表中添加别的记录。幻读就是一个事务用一样的 SQL 多次查询,结果每次查询都会发现查到一些之前没看到过的数据。之前读到的数据在这次读到的数据中没有发生变化,但是它的结果集发生了变化

💥举个例子:

你一个事务 A,先发送一条 SQL 语句,里面有一个条件,要查询一批数据出来,如 SELECT * FROM table WHERE id > 10。然后呢,它一开始查询出来了 10 条数据。接着这个时候,别的事务 B往表里插了几条数据,而且事务 B 还提交了,此时多了几行数据。

接着事务 A 此时第二次查询,再次按照之前的一模一样的条件执行 SELECT * FROM table WHERE id > 10 这条 SQL 语句,由于其他事务插入了几条数据,导致这次它查询出来了 12 条数据

 解决幻读问题:串行化

 数据库使用"串行化"这样的方式来解决幻读。彻底放弃并发处理事务,一个接一个的串行的处理事务。这样做并发的程度是最低的(效率是最慢的),隔离性是最高的(准确性也是最高的)

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

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

相关文章

Arduino ESP8266基于ESPAsyncWebServer 网页GPIO控制

Arduino ESP8266基于ESPAsyncWebServer 网页GPIO控制 📍相关篇《Arduino ESP8266利用AJAX局部动态更新网页内容》 📺控制页面演示: 🌿在手机上可以通过接入ESP8266的WIFI,通过浏览器方位192.168.4.1进行网页页面操控引脚以及查看esp8266信息。 ✨本项目是基于github上…

[oeasy]python0143_主控程序_main

主控程序 回忆上次内容 上次把 apple.py 拆分成了 输入主函数 引用模块中变量的时候 要带上包(module)名 get_fruits.aget_fruits.b 最终 拆分代码 成功! 可以将程序 再拆分成 输入输出 然后 再由主函数调用吗?🤔 建立主控 新建一个 ma…

【Java笔试强训 10】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥井字棋 …

大数据技术之大数据概论

第1章 大数据概念 大数据(Big Data): 指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产 大数据主要解决,海量数据的采集、存…

【吴恩达推荐】《ChatGPT Prompt Engineering for Developers》- 知识点目录

《ChatGPT Prompt Engineering for Developers》 1 Introduction 2 Guidelines Principle 1: Write clear and specific instructions Tactic 1: Use delimiters Tactic 3: “If-statement” Check whether conditions are satisfiedCheck assumptions required to do the …

RDD的Stage划分原理

1. 什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark 中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。在Spark 中,对数据的所有操作不外乎创建RDD、转化已有RDD 以…

JavaBeaneljstl

1.JavaBean 1.1 什么是JavaBean JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器 简单一点:建一个类,给一个无参的构造方法. 它就是JavaBean,对应JavaBean来说&#x…

【C++】程序员的屠龙母鸡:二叉树进阶OJ题详解

不会自动生成,还是我自己写目录吧 -.- 文章目录 前言一、稍微简单一点的二叉树OJ题二、相对困难一点的二叉树OJ题总结 前言 在看这篇文章前希望大家是学过二叉树的,不然理解起来可能会比较费劲,但我会尽自己的努力让大家学会这些题&#xf…

TensorFlow会被JAX代替吗,使用JAX训练第一个机器学习模型

上期文章我们分享了JAX的概念,Jax 是来自 Google 的一个相对较新的机器学习库。它更像是一个 autograd 库,可以区分每个本机 python 和 NumPy 代码。 “PythonNumPy 程序的可组合转换:微分、向量化、JIT 到 GPU/TPU 等等”。该库利用 grad 函…

vue 视频播放插件vue-video-player自定义样式

1、背景 项目中有涉及视频播放的需求,并且UI设计了样式,与原生的视频video组件有差异,所以使用了vue-video-player插件,并对vue-video-player进行样式改造,自定义播放暂停按钮、全屏按钮、时间进度条样式等 2、效果图…

10分钟叫你如何学会组织Prompt语言同AI沟通

提示词(Prompt)是与AI模型交流的语言,用以告诉AI模型想要生成的图像的特征。提示词的准确性、精准度直接决定了生成的图像是否符合我们的预期。 基础介绍 AIGC提示词通常由多个单词、词组或短句构成,以***,***分割组成&#xff…

如何更改Windows服务器时间

Windows操作系统自带时间同步功能,它会自动从互联网时间服务器获取时间,以保证系统时间的准确性。但是,有时候我们需要更改时间服务器,以获得更准确的时间同步。小编将为大家介绍如何更改Windows时间服务器,以及Window…

java基础知识——22.lambda表达式

这篇文章,我们来讲一下java的lambda表达式 目录 1.初识lambda表达式 2.lambda表达式介绍 2.1 函数式编程 2.2 lambda表达式的具体格式 2.3 Lambda表达式的好处 2.4 Lambda的省略写法 1.初识lambda表达式 首先,我们来看一下lambda表达式的应用 下…

运维——ssh无法登录云服务器

0x00 概述 一般来讲,无法登录ssh的原因挺多,如果无法登录云服务器,则除了要检查ssh端口是否放行,防火墙状态外,还需要检查云服务器web控制台入站规则是否开放了对应端口。如果你前面检查都是正常,那么还需…

实战打靶集锦-017-potato

提示:本文记录了博主的一次打靶过程 目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 Apache探查4.2 ProFTPD探查4.2.1 strcmp()函数绕过4.2.2 查找apache日志文件4.2.3 查看/etc/passwd文件4.2.4 破译密码4.2.5 突破边界 5. 提权5.1 系统信息枚举5.2 定时任…

基于Yolov5的NEU-DET钢材表面缺陷检测,优化组合新颖程度较高:CVPR2023 DCNV3和InceptionNeXt,涨点明显

1.钢铁缺陷数据集介绍 NEU-DET钢材表面缺陷共有六大类,分别为:crazing,inclusion,patches,pitted_surface,rolled-in_scale,scratches 每个类别分布为: 训练结果如下: 2.基于yolov5s的训练 map值: 2.1 Inception-MetaNeXtStage 对应博客:https://cv2023.blog.csdn.n…

实验5 彩色图像处理与图像变换

文章目录 一、实验目的二、实验内容1. 彩色图像平滑。(课本P310 例6.12)2. 彩色边缘检测。(课本P318 例6.16)3. 一维小波变换。(课本P364 例7.20)4. 二维小波变换。(课本P369 例7.22)5. 小波包分解。(课本P376 例7.24) 一、实验目的 掌握RGB彩色模型和HSI彩色模型之间的转换方…

C语言指针的使用

文章目录 前言一、指针基本概念介绍二、指针的大小三、使用指针访问变量和变量地址四、使用指针遍历数组总结 前言 一、指针基本概念介绍 在 C 语言中,指针是一种用于存储内存地址的数据类型。指针可以存储任何数据类型的内存地址,包括基本数据类型、数…

C语言之单链表的实现以及链表的介绍

一、为什么会存在链表 因为我们常用的顺序表会存在以下的一些问题: 1. 中间/头部的插入删除,时间复杂度为O(N) 2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。 3. 增容一般是呈2倍的增长,势必会有一定…

算法的特性和空间复杂度---数据结构

目录 前言: 1.算法 1.1算法的特性 1.2设计算法 2.空间复杂度 3.学习复杂度的意义 ❤博主CSDN:啊苏要学习 ▶专栏分类:数据结构◀ 学习数据结构是一件有趣的事情,希望读者能在我的博文切实感受到数据之间存在的关系&#xff…