【MYSQL】索引和事务

🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈

在这里插入图片描述
本期内容讲解 MySQL 中的索引和事务,在学习的过程中,我们需要经常问自己为什么

文章目录

  • 1. 索引
    • 1.1 索引的概念
    • 1.2 索引的目的
      • 1.2.1 为什么使用索引会加快查询速度?
    • 1.3 索引的使用
    • 1.4 索引的分类
    • 1.5 索引的优缺点
    • 1.6 MySQL 的默认存储引擎 InnoDB 背后的数据结构 —— B+ 树
      • 1.6.1 B树
      • 1.6.2 B+树
  • 2. 事务
    • 2.1 事务的概念
    • 2.2 事务的使用
    • 2.3 事务的四大特性 —— ACID
      • 2.3.1 原子性
      • 2.3.2 一致性
      • 2.3.3 持久性
      • 2.3.4 隔离性
        • 1) 脏读
        • 2)不可重复读
        • 3)幻读

1. 索引

1.1 索引的概念

概念】索引是一种特殊的文件,包含着对数据表里所有记录的引用指针,可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现 ~

1.2 索引的目的

目的】就比如说,本期文章带有目录(笔者每篇文章都带有目录)~ 通过目录,我们就对这期内容有一个大致的了解,并且通过目录,我们可以快速的定位我们想要的内容,而索引的作用和目录的作用类似,都是加快查询速度~

1.2.1 为什么使用索引会加快查询速度?

首先我们知道,MySQL 数据库文件存储在磁盘上的,磁盘 I/O 是数据库操作比较耗时的一部分

  • 无索引,数据库会进行全表扫描,它必须读取表中的每一行数据来查找匹配的行,时间效率为 O(n),当表的数据量非常大时,就会导致大量的磁盘 I/O 操作,非常耗时间!
  • 有索引,可以直接跳到索引指示的数据位置,不用扫描整张表,大大减少了磁盘 I/O 操作的次数,减少时间,如 MySQL 的默认存储引擎 InnoDB 默认使用 B+ 树来作为索引的数据结构 ,而 B+ 树的查询效率非常高,时间复杂度是O(logN)!(本期内容后面将会具体介绍 B+ 树)

我们知道索引是一种特殊的文件,MySQL 索引文件主要存储索引,数据库文件存储的数据不仅包括全部数据,还包括索引等信息,索引文件与数据库文件相比,体积小很多,通过查询索引,再映射到数据库记录,查询效率就会高很多~

举例
还是结合目录来看,通过目录可以快速定位到哪一个位置,比如查字典,可以通过目录,快速找到需要的内容在哪一页,没有目录的话,我需要从字典的第一页,每一页一页的翻,找到想要的内容,想想是不是很耗时呢?索引的作用也是如此!加快查询的作用!

1.3 索引的使用

情况一】对于创建主键约束唯一约束外键约束时,会自动创建对应列的索引

  1. 首先创建一个 student 表,以 id 为主键(此时创建了主键约束,会自动创建对应列的索引)
 create table student (id int primary key,username varchar(50));

在这里插入图片描述

  1. 查看索引
 show index from 表名;

从下图中可以看到,主键 id,自动创建了索引
在这里插入图片描述
如果 id 没有加主键约束,是不会自动创建索引的~ 如下图:

在这里插入图片描述
情况二创建普通索引,对于非主键、非唯一约束、非外键的字段,可以创建普通索引

  1. 创建索引
create index 索引名 on 表名(列名);

在这里插入图片描述

  1. 删除索引
drop index 索引名 on 表名;

在这里插入图片描述

(可以动手多操作哦,才会记忆深刻呀~更加利于理解哦!)

1.4 索引的分类

在这里插入图片描述

1.5 索引的优缺点

优点

  • 加快查询速度:通过索引可以快速定位到满足查询条件的数据行,减少数据的扫描范围,从而提高查询效率。例如,在一个包含大量用户信息的表中,如果经常根据用户姓名进行查询,为姓名列创建索引后,查询速度大大提升;
  • 保证数据唯一性:可以通过创建唯一索引来确保表中某列或某些列组合的数据具有唯一性,防止出现重复数据,比如,在用户表中,为身份证号码列创建唯一索引,就可以保证每个用户的身份证号码是唯一的;
  • 支持数据排序:索引可以按照指定的列进行排序,当查询需要对结果进行排序时,使用索引可以避免数据库在查询时进行额外的排序操作,提高查询性能。比如,在订单表中,为订单时间列创建索引,当按照订单时间查询并排序订单时,数据库可以直接使用索引来获取有序的数据。

缺点

  • 占用存储空间:索引本身需要占用一定的磁盘空间来存储索引结构,随着数据量的增加和索引数量的增多,占用的空间也会相应增大,比如,一个大型数据表创建多个索引后,可能会使数据库文件的大小增加很多;
  • 增加维护成本:在数据插入、更新和删除时,索引也需要进行相应的更新操作,这会增加数据库的维护成本和时间开销。例如,当向表中插入一条新记录时,如果该表有多个索引,那么每个索引都需要进行更新以保证索引的准确性和一致性;
  • 降低写入性能:由于写入数据时需要同时更新索引,所以会降低写入操作的性能,比如,在批量插入数据时,没有索引的表插入速度会比有索引的表快很多

1.6 MySQL 的默认存储引擎 InnoDB 背后的数据结构 —— B+ 树

在本期内容开头就介绍了,数据库索引的作用是为了加快查询速度的~ 那么,我们会思考,其索引背后的数据结构是什么呢? 并且能够让它加快查询速度!

我们可以回想一下之前学过的数据结构,其中,二叉搜索树和哈希表就是比较适合查询的,但是很遗憾的是,它们两个都不适合于数据库索引的底层数据结构:

  • 二叉搜索树: 二叉搜索树查找的时间复杂度是树的高度,我们知道数据库一般都是将数据存储在硬盘上,数据量很大的时候,如果使用二叉搜索树,则树的高度也会很大,导致查询效率会很慢,
  • 哈希表:哈希表它是由数组和链表组成的,查找的时间复杂度为 O(1),尽管时间复杂度低,但是,它的 key 不是有序的,并且对于数据库中的大于、小于的范围查找或者是 LIKE 类似的模糊查询哈希表都是不能够做到的,比如,我们要查询学生的序号在 202110120510 到 202110120534 之间的学生信息,哈希表是做不到的~

噔噔噔!!! 这里,就要介绍一种特殊的数据结构,B+树 —— 专门为了数据库索引量身定做的数据结构!

1.6.1 B树

介绍 B+ 树前,先介绍一下 B 树,也叫做 B- 树,注意!!! 这里的 ‘-’ 不是减号,只是连接符哦! 很多小伙伴看到有 B+ 树,可能会想当然的以为也有 B- 树

B树可以认为是一颗N叉搜索树,结构如下:

在这里插入图片描述

我们可以通过图看到,当节点的子树多了,节点上保存的 key 就多了,在相同个数 key 的情况下,B 树的高度就比二叉搜索树的高度要低很多,对 IO 操作的次数就越少,这样查找性能就会比较高!

1.6.2 B+树

我们先来了解一下 B+ 树的特点~

B+ 树的特点

  • 一个节点可以存储 N 个 key,N 个 key 可以划分出 N 个子区间(不是 N+1 个)
  • 每一个 key 都会在子区间出现,且为子区间的最大值
  • B+ 树的叶子节点是首尾相连的,类似于一个链表
  • B+ 树的非叶子节点只用于索引并不保存数据,只有叶子节点存储着索引和数据

到底是一个什么样的数据结构呢? 我们一起来看看!

在这里插入图片描述
既然有 B 树,那么为什么还要有 B+ 树呢?

我们一起来分析一下 B 树的优缺点:

  • B树优点:每个节点都存储了索引和对应的数据,在查找离根节点近的节点时,查找效率是很高的,不用每次都查找到叶子节点(与B+树相比,因为 B+ 树必须得查找到叶子节点)
  • B树缺点
    不利于范围查找,即不利于区间查找,比如要找 5 - 14 的索引值,那么 B 树就需要多次从根节点逐个查找,而 B+ 树的叶子节点是链表连接起来的,且是从小到大依次有序的,在 B+ 树中,只用找到 5 索引 和 14 索引的叶子节点,从 5 沿着链表遍历到 14 即可!

再来分析一下 B+ 树的优点:

  • 查询任意一个节点最终都会落到叶子节点每次 IO 访问次数是一样的
  • B+ 树的所有叶子节点构成了一个完整的链表,适合进行范围查找
  • 只有叶子节点是存储着完整的数据,非叶子节点只记录索引,这样这些非叶子节点占用的内存就十分的小,又进一步减小 IO 操作次数

补充知识

1)回表

比如在有一些表中,有多个索引,如上述创建的 student 表里,我们在 username 这一列创建了一个索引,此时,表的数据还是会根据主键id 构建出 B+ 树,通过叶子节点将数据组织起来,其次,会根据 username 这个列创建一个B+树,但这个 B+ 树的叶子节点只存储主键id是什么,此时如果你是通过 username 这个索引来查找的,会通过叶子节点拿到的 id 索引再去由 id 创建的B+树里再查一次,即查两次B+树,上述过程,在数据库中就叫回表

上述过程是 Mysql 自动完成的,用户是完全感知不到的,这是因为主键索引也是聚簇索引,叶子节点存储整个数据和索引,而其他索引就是非聚簇索引,叶子节点只存储主键和索引,因此,使用非聚簇索引进行查询的时候需要再拿着这个查询到的主键再在聚簇索引中进行一次查询,即回表

2)聚簇索引和非聚簇索引

在 MySQL 的 默认 InnoDB 引擎中,每个索引都会对应一颗 B+ 树,而聚簇索引和非聚簇索引最大的区别在于叶子节点存储的数据不同,聚簇索引叶子节点存储的是行数据,因此通过聚簇索引可以直接找到真正的行数据;而非聚簇索引叶子节点存储的是主键信息,所以使用非聚簇索引还需要回表查询,因此,我们可以得出聚簇索引和非聚簇索引的区别主要有以下几个:

  • 存储内容聚簇索引叶子节点存储的是行数据;而非聚簇索引叶子节点存储的是聚簇索引,通常是主键 ID;
  • 效率聚簇索引查询效率更高,而非聚簇索引需要进行回表查询,因此性能不如聚簇索引;
  • 数量上:聚簇索引一般为主键索引,而主键一个表中只能有一个,因此聚簇索引一个表中也只能有一个,而非聚簇索引则没有数量上的限制

2. 事务

2.1 事务的概念

我们先来想一下这个场景,七夕节到了,小丁准备给他的女朋友小万转账 1314,那么 sql 语句应该如下:

update account set  money = money - 1314 where name = ‘小丁’;
update account set  money = money + 1314 where name = ‘小万’;

假设在执行完第一条语句后,数据库突然崩溃了或者主机宕机了,此时就出现了问题,小丁的钱扣了,但是小万没有收到转账,小万就会很生气,觉得没转就没转,而不能这样骗她!小丁就百口莫辩了,明明自己转了呀!现实生活中,有很多这样的支付场景,那么如何解决呢?

事务则是解决上述问题的,事务指的是逻辑上一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败,在不同环境中,都可以有事务,对应在数据库中,就是数据库事务,通俗的来讲,就是把 sql 语句打包在一起,要么全部都执行成功,要么全部都不执行,不会出现执行到一半的情况,注意,这里的全部都不执行,并不是真的没执行,而是执行到一半,出现问题后,选择恢复到原来的样子,将数据灰度到未执行的状态,这个恢复操作,就叫做 “回滚”(rollback)

2.2 事务的使用

  1. 开启事务:start transaction;
  2. 中间放要执行的 sql 语句
  3. 回滚或提交: rollback/commit;
    (说明: rollback表示“全部失败”,commit表示“全部成功”)

具体代码如下:

start transaction; //开启事务
update account set money = money - 1314 where name = '小丁';
update account set money  =money + 1314 where name = '小万';
commit;   //提交事务

2.3 事务的四大特性 —— ACID

2.3.1 原子性

事务的初心就是原子性事务是一个不可分割的单位,数据库事务里的 sql 语句要么全部执行,要么全部不执行,不会出现执行一半的情况,如果执行一半出现问题就会进行 “回滚” 操作(强调事务是一个整体)

2.3.2 一致性

事务执行前后,数据都是一个合法的状态,就像上面的转账情况,在转账前和转账后数据都应该是一个合法的状态,是一致的(强调数据的合法状态)

2.3.3 持久性

事务修改的内容是写入硬盘的,持久存在,重启也不会消失(强调事务修改内容都是写入硬盘的,具有持久性)

2.3.4 隔离性

多个事务并发执行的时候,每个事务应该感受不到其他事务的存在,各个事务是隔离的(强调多个事务并发执行,各事务是隔离的,相互不影响)

但是,不同的事务隔离级别会导致不同的并发问题,如脏读,不可重复读,幻读,下面将具体介绍这三个问题:

1) 脏读

概念】脏读就是一个事务读取到了另一个未提交事务修改的数据

举例】事务A 对数据库中的小万余额进行读取,余额为 100,接着再执行更新操作,将余额更新为 500,此时,并没有提交事务,而另一边,事务B 对数据库中的小万余额进行读取,那么事务B就读取到了事务A更新的金额,余额为 500,但是此时事务A并没有提交事务!随时可能发生回滚操作,如果上述情况事务发生回滚,那么余额为 100,而事务B读取到了事务A的过期数据500,这个就是脏读

解决方式】给事务A修改数据这个操作进行写加锁当事务A修改数据的时候,其它事务不能对该数据进行读取,这样就意味着此时写操作和读操作不能并发执行了,降低了并发程度,即降低了小效率,但是提高了隔离性,即提高了数据的准确性

2)不可重复读

概念】不可重复读就是一个事务多次重复读取一个数据,如果出现了前后两次读取的数据不一致的情况

举例】一个事务A对小万的余额进行读取,此时有一个事务B对小万的余额进行更新并提交事务,这样,事务A对小万的余额再进行读取的时候,就会发现,前后两次读取的数据不一样,这就是不可重复读

解决方式】给事务A对数据进行读取的时候进行读加锁,当事务A对数据进行读取操作的时候,其它事务不能对该数据进行修改,此时,又降低了并发程度,提高了隔离性

3)幻读

概念】幻读就是在一个事务内多次查询符合条件的记录数量,出现了前后查询数量不一致的情况

举例】事务A在数据库中查询余额大于500的用户,此时有十条记录,但是事务B此时插入了一条余额大于500的用户,并提交事务,这个时候事务A再进行查询余额大于500的用户,就查询到十一条记录,这个就是幻读

解决方式】数据库使用 “串行化” 的操作来解决幻读的问题,就是彻底放弃事务并发,一个接一个的串行执行事务,此时,并发程度最低,效率最低,隔离性最高,数据准确性最高!

数据库提供的四个隔离级别

  • read uncommitted(读未提交)
    没有任何锁限制,并发程度最高,隔离性最低,会发生上述三种问题
  • read committed(读已提交)
    给写加锁,并发程度降低,隔离性增加,但会产生“不可重复读”和“幻读”问题
  • repeatable read(可重复读)(MySQL的默认隔离级别)
    给读写都加锁,并发程度进一步降低,隔离性进一步增加,但可能会产生“幻读”问题
  • serializable(串行化)
    彻底实行串行化,并发程度最低,隔离性最高

💛💛💛本期内容回顾💛💛💛
在这里插入图片描述

✨✨✨本期内容到此结束啦~

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

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

相关文章

2021年蓝桥杯第十二届CC++大学B组真题及代码

目录 1A:空间(填空5分_单位转换) 2B:卡片(填空5分_模拟) 3C:直线(填空10分_数学排序) 4D:货物摆放(填空10分_质因数) 5E&#xf…

PicGo安装与配置-Gitee图床

1、 前言 平时使用Typora写文章,上传文章到第三方平台上去都要把图片一个一个上传上去,于是我就百度了有没有什么方法可以省略这一步骤,我发现Typora可以用PicGo+Gitee图床方式,这个挺容易的,我把安装的过程在此记录下来。 PicGo是一个用于快速上传图片并获取图片 URL 链…

html css js网页制作成品——HTML+CSS+js迪奥口红网站网页设计(4页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨‍&#x1f…

重学Java基础篇—如何优雅的删除HashMap元素

在Java中优雅地删除HashMap元素需要注意遍历时的安全性和代码的简洁性。 以下是几种推荐的方法: 1. 使用迭代器遍历并删除(传统方式) 在遍历时通过迭代器的remove() 方法删除元素,避免ConcurrentModificationException异常。 H…

26考研——图_图的遍历(6)

408答疑 文章目录 三、图的遍历图的遍历概述图的遍历算法的重要性图的遍历与树的遍历的区别图的遍历过程中的注意事项避免重复访问遍历算法的分类遍历结果的不唯一性 广度优先搜索广度优先搜索(BFS)概述BFS 的特点广度优先遍历的过程示例图遍历过程 BFS …

2025-03-24 学习记录--C/C++-PTA 习题7-6 统计大写辅音字母

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 习题7-6 统计大写辅音字母 英文辅音字母是除A、E、I、O、U以外的字母。本题要求编写程序,统计给…

在vitepress中使用vue组建,然后引入到markdown

在 VitePress 中&#xff0c;每个 Markdown 文件都被编译成 HTML&#xff0c;而且将其作为 Vue 单文件组件处理。这意味着可以在 Markdown 中使用任何 Vue 功能&#xff0c;包括动态模板、使用 Vue 组件或通过添加 <script> 标签为页面的 Vue 组件添加逻辑。 值得注意的…

常见中间件漏洞之一 ----【Tomcat】

中间件Tomcat介绍&#xff1a; tomcat是⼀个开源⽽且免费的jsp服务器&#xff0c;默认端⼝ : 8080&#xff0c;属于轻量级应⽤服务器。它可以实现 JavaWeb程序的装载&#xff0c;是配置JSP&#xff08;Java Server Page&#xff09;和JAVA系统必备的⼀款环境。 在历史上也披露…

Spring Cloud之负载均衡之LoadBalance

目录 负载均衡 问题 步骤 现象 什么是负载均衡&#xff1f; 负载均衡的一些实现 服务端负载均衡 客户端负载均衡 使用Spring Cloud LoadBalance实现负载均衡 负载均衡策略 ​编辑 ​编辑LoadBalancer原理 服务部署 准备环境和数据 服务构建打包 启动服务 上传J…

量化研究--小果聚宽交易系统上线高速服务器,提供源代码

文章链接量化研究--小果聚宽交易系统上线高速服务器&#xff0c;提供源代码https://mp.weixin.qq.com/s/HecSeAvmaCyVCsPhvxA0xg 今天大家反应以前的服务器比较慢&#xff0c;与200多人在使用这个系统&#xff0c;反应比较慢&#xff0c;实时数据请求服务器&#xff0c;服务器还…

蓝桥杯python组备考2(b站课程笔记)超详细

语法进阶 一、列表推导式 想讲解一下示例4到示例7的代码&#xff1a; 4、循环n次生成n个零放进列表中&#xff0c;其实也就是相当于[0]*n&#xff08;列表乘法&#xff0c;将原来的列表循环n次产生一个新的列表&#xff09;&#xff0c;接着在循环n次产生n个这样的列表&#x…

【大模型LLM第十四篇】Agent学习之anthropic-quickstarts Agent

前言 对于anthropic api的快速使用&#xff0c;在github上有几个example Customer Support Agent&#xff1a;由 Claude 提供支持的客户支持代理。该项目演示了如何利用 Claude 的自然语言理解和生成功能来创建可访问知识库的 AI 辅助客户支持系统。Financial Data Analyst &…

用DrissionPage升级网易云音乐爬虫:更稳定高效地获取歌单音乐(附原码)

一、传统爬虫的痛点分析 原代码使用requests re的方案存在以下局限性&#xff1a; 动态内容缺失&#xff1a;无法获取JavaScript渲染后的页面内容 维护成本高&#xff1a;网页结构变化需频繁调整正则表达式 反爬易触发&#xff1a;简单请求头伪造容易被识别 资源消耗大&am…

2025年渗透测试面试题总结- PingCAP安全工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 PingCAP安全工程师 一、SQL注入判断数据库类型技术分析 1. 常规判断方法 2. 盲注场景下的判断 3. 补…

【加密社】如何创建自己的币圈工具站

需要准备的工作 1.域名 2.服务器 周末的时候主要弄了快讯这方面的代码 我这里用的是星球日报的api&#xff0c;也可以订阅他们的rss&#xff0c;这部分在github上是开源的 https://github.com/ODAILY 我这里用的是WordPressonenav主题&#xff0c;然后用小工具在主页展示&am…

Oracle归档配置及检查

配置归档位置到 USE_DB_RECOVERY_FILE_DEST&#xff0c;并设置存储大小 startup mount; !mkdir /db/archivelog ALTER SYSTEM SET db_recovery_file_dest_size100G SCOPEBOTH; ALTER SYSTEM SET db_recovery_file_dest/db/archivelog SCOPEBOTH; ALTER SYSTEM SET log_archive…

Apache Hive:基于Hadoop的分布式数据仓库

Apache Hive 是一个基于 Apache Hadoop 构建的开源分布式数据仓库系统&#xff0c;支持使用 SQL 执行 PB 级大规模数据分析与查询。 主要功能 Apache Hive 提供的主要功能如下。 HiveServer2 HiveServer2 服务用于支持接收客户端连接和查询请求。 HiveServer2 支持多客户端…

FPGA_DDS_IP核

接下来对FPGA的DDS的ip核进行学习。 首先对DDS需要有些了解 DDS信号发生器采用直接数字频率合成&#xff08;Direct Digital Synthesis&#xff0c;简称DDS&#xff09;技术&#xff0c;简单来说就是 需要一个系统频率和一个输入的数字数据 &#xff0c;用这个系统频率计算出…

欢迎来到未来:探索 Dify 开源大语言模型应用开发平台

欢迎来到未来&#xff1a;探索 Dify 开源大语言模型应用开发平台 如果你对 AI 世界有所耳闻&#xff0c;那么你一定听说过大语言模型&#xff08;LLM&#xff09;。这些智能巨兽能够生成文本、回答问题、甚至编写代码&#xff01;但是&#xff0c;如何将它们变成真正的实用工具…

计算机工具基础(七)——Git

Git 本系列博客为《Missing in CS Class(2020)》课程笔记 Git是一种分布式版本控制系统&#xff0c;被其跟踪的文件可被查询精细到行的修改记录、回退版本、建立分支等 模型 一般流程&#xff1a;工作区 → \to →暂存区 → \to →仓库(本地 → \to →远端) 工作区&#xff1…