【MySQL】索引与事务

在这里插入图片描述

  • 👑专栏内容:MySQL
  • ⛪个人主页:子夜的星的主页
  • 💕座右铭:前路未远,步履不停

目录

  • 一、索引
    • 1、使用场景
    • 2、使用索引
      • 创建索引
      • 查看索引
      • 删除索引
    • 3、底层数据结构(非常重要)
  • 二、事务
    • 1、概念
    • 2、使用
    • 3、特性(非常重要)
    • 4、四种隔离级别


一、索引

索引可以简单理解为是一本书的目录。
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
image.png
一个表中有很多数据,在查询数据的时候,最基本的方法就是遍历表,一条条的进行筛选。因此,就可以给这个表建立索引,来提高查找速度。索引是以“列”为维度进行建立的。

1、使用场景

索引是用来提高查询效率的,但是也有一定的缺陷:

  • 消耗额外的空间。
  • 有可能会拖慢增删改的速度。因为,新增的时候,不光要往表里面插入数据,还要修改索引。但是如果涉及到索引列的删除/修改,这个时候也需要同时维护索引。

2、使用索引

创建索引

create table student (id int primary key , name varchar(20));create table student (id int unique , name varchar(20));create table student (id int primary key , name varchar(20),classId int ,foreign key (classId) references class (classId));

当表中存在主键的时候,内部就会自动给这个列创建索引。
因为主键不允许重复,因此进行插入或者修改,就需要先进行查询,看看插入/修改的结果是不是已经存在。所以,建立索引后就会加快频繁的查询速度。
前面的都是自动创建的索引,下面我们了解一下手动创建索引的方法。

create index 索引名 on 表名(字段名)
create index student_name on students(name);

image.png
手动创建索引操作,可能会非常危险。如果表是空的或者表里面包含的数据本身就不多,这个时候创建索引就没有事。但是,如果表非空,并且里面包含了非常多的数据,那么创建索引会引起非常大规模的硬盘 IO 操作,进一步导致数据库被卡死。

查看索引

show index from 表名;

image.png

删除索引

drop index 索引名 on 表名;

image.png
删除索引,只能针对手动创建的索引。自动生成的索引,是不能被删除的。
删除索引的操作也是非常危险的,因为也会出现大规模的硬盘 IO
【问题】如果现在确实需要给一个已经有很多数据的表创建/删除索引,并且这个数据库还是生产环境的数据库,怎么办?
数据库服务器往往不是单台服务器,为了系统的可靠性,往往会搞多个 MySQL 服务器节点,这些节点的数据都是一样的,能够提供相同的服务。所以,我们可以先准备一台新的服务器,把表和索引都创建好,然后把数据都导入过来,再把要替换的 MySQL 服务器关闭,把新的 MySQL 服务器替换上去就行了。

3、底层数据结构(非常重要)

MySQL 的索引的数据结构到底是什么样的数据结构,并不是定式。这取决于 MySQL 使用那个存储引擎(MySQL 这个程序包含很多模块,用来存储数据的模块就是存储引擎)。具体如何存储数据,MySQL 支持多种存储方案,当下最主流的方式是 innodb

以往的数据结构都是在内存中的,数据库这块组织数据使用的数据结构则是在硬盘上的。内存上的数据结构,对访问操作来说不敏感。找数据的过程花费的时间多,真正访问的时间不多。硬盘上的数据结构,对于访问操作来说,比较敏感。而读写一次硬盘开销又远大于内存。

索引主要目的是为了进行快速查找,hash 不能够进行范围查询,不能够进行模糊匹配。而红黑树,能进行范围查询和模糊匹配,但是会引入较多的硬盘 IO 操作。所以,innodb 这个存储引擎的底层数据结构是B+树。B +树是 B 树的一种改进。B 树的核心思路和之前介绍过的二叉搜索树差不多,B 树本质上是一个 N 叉搜索树。
MySQL索引的底层数据结构主要是B+树和哈希表。

  1. B+树索引:这是MySQL中最常用的索引类型,尤其是在InnoDB存储引擎中。B+树索引适用于全值匹配、匹配列前缀、范围查找和排序操作。其特点是所有的值都是有序的,并且叶子节点之间是相连的,这使得范围查询变得非常高效。
  2. 哈希索引:哈希索引是基于哈希表实现的,它适用于等值比较查询,如=, IN()等操作。哈希索引的优势在于快速的查找速度,但它不支持范围查找。在MySQL中,哈希索引主要被Memory存储引擎使用。

除此之外,MySQL还支持全文索引和空间索引等,但这些索引的底层数据结构和B+树及哈希表有所不同。全文索引用于文本数据的搜索,而空间索引用于地理空间数据。
使用 B+树作为主要索引的关键优势:

  1. 有效的范围查询和排序:B+树的叶子节点包含了所有键值,并且这些叶子节点是相互链接的。这使得执行范围查询(如检索一定范围内的所有记录)和排序操作更加高效,因为可以简单地在叶子节点间顺序遍历。
  2. 高效的磁盘读写:B+树的结构使得磁盘I/O操作更加高效。它的节点通常有很多子节点,这意味着树的高度较低,从而减少了磁盘访问次数。在数据库操作中,磁盘I/O通常是性能瓶颈,因此减少I/O操作可以显著提高性能。
  3. 页的分裂和合并效率:当B+树的节点(页)满时,它们可以被有效地分裂。相反,当节点的利用率低下时,可以将它们合并以节省空间。这种灵活性是B+树特别适合动态数据库环境的一个重要原因。
  4. 全键值存储在叶子节点:在B+树中,所有的数据都存储在叶子节点中,而非叶子节点仅存储键值和指向子节点的指针。这种结构使得每个叶子节点可以被用作数据层,从而简化了数据的访问和管理。
  5. 更好的缓存利用率:因为B+树的结构使得大量的查询能够通过访问树的顶部几层就能完成,这些常访问的节点容易被缓存在内存中,从而减少了磁盘访问次数。
  6. 适应性强:B+树可以很好地适应各种类型的查询,包括点查询和范围查询,这使得它成为通用数据库系统中的理想选择。

二、事务

1、概念

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。 在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。事务的本质就是为了把多个操作打包成一个操作来完成。(打包成一个操作:要么全部都执行成功,要么一个都不执行)
【注意】一个都不执行,并不是真的不执行。执行不执行成功,执行了才知道。
假设事务中有 3 个操作:先执行 1 再执行 2 最后执行 3,如果执行到中间出错了,就需要自动把前面已经成功执行的操作还原回最初没有执行的模样。本质上,这里的一个都不执行,并不是没有执行,而是看起来跟没执行一样。这个还原数据的过程,叫做回滚(rollback)。
【问题】回滚是咋实现的 ?
只需要把事务中执行的每个操作,都记录下来(通过特定的日志)。如果需要回滚,就按照之前的操作进行逆操作即可。

2、使用

(1)开启事务:start transaction;
(2)执行多条SQL语句
(3)回滚或提交:rollback/commit;
说明:rollback 即是全部失败,commit 即是全部成功。一个事务,必须以 commitrollback 这两个操作结尾。如果没有这两个操作,接下来的各种 sql 操作都会被认为是事务的一部分。

3、特性(非常重要)

**原子性:**事务是一个不可分割的工作单元,事务中的操作要么全部完成,要么全部不完成。如果事务中的一个操作失败,整个事务将回滚到事务开始之前的状态,就像这些操作从未被执行过一样。
**一致性:**事务必须保持数据库的一致性。这意味着事务的执行结果必须使数据库从一个一致的状态转换到另一个一致的状态。一致性包括数据的完整性、业务规则、关系约束等。
**隔离性:**并发执行事务的适合,隔离性会在执行效率和数据可靠之间做出权衡。“隔离”描述的是同时执行的事务之间,相互影响。隔离性越高,并发就越低,数据越可靠,性能就越低。 隔离性通过不同的隔离级别实现,如可串行化、读已提交、读未提交和可重复读,每个级别都有不同的并发控制方法和可能遇到的问题(如脏读、不可重复读、幻读)。
【问题】什么是脏读、不可重复读、幻读?

  1. 脏读(Dirty Read)
    • 定义:脏读发生在一个事务读取了另一个未提交事务的数据。如果那个未提交的事务最终失败并回滚,那么第一个事务读取的数据就是不一致的,因为它读取了永远不会被提交的数据。
    • 例子:事务 A 修改了一条记录,但还没有提交。与此同时,事务 B 读取了同一条记录。如果 A 回滚了它的改变,B 读取的数据就是无效的。
    • 解决:写加锁,提交之前不可读。
  2. 不可重复读(Non-repeatable Read)
    • 定义:不可重复读指的是在同一个事务中,两次读取同一数据集合时,由于其他事务的修改操作,导致两次读取的数据不一致。
    • 例子:事务 A 读取了一条记录,随后事务 B 修改了这条记录并提交。当事务 A 再次读取同一记录时,发现数据已经发生变化。
    • 解决:读加锁,读的适合不可写。
  3. 幻读(Phantom Read)
    • 定义:幻读与不可重复读类似,但它涉及到数据集合的数量变化。一个事务在读取某个范围的记录时,另一个事务插入或删除了该范围内的记录,导致第一个事务再次读取时发现有“幻影”数据。
    • 例子:事务 A 读取了一个范围内的所有记录。同时,事务 B 插入了一个新的记录到这个范围内。当事务 A 再次读取这个范围的记录时,会发现一个之前未见的新记录。
    • 解决:彻底串行化,完全放弃并发执行。

**持久性:**一旦事务提交,对数据所做的更改就是永久性的,即使系统发生故障也不会丢失。持久性通常通过数据库管理系统的恢复和日志机制来保证。

4、四种隔离级别


读未提交(Read Uncommitted)

  • 在这个级别下,事务可以读取未被其他事务提交的数据。这是最低的隔离级别,允许脏读、不可重复读和幻读。

读已提交(Read Committed)

  • 事务只能读取已经被其他事务提交的数据。这个级别可以避免脏读,但不可重复读和幻读仍然可能发生。

可重复读(默认)(Repeatable Read)

  • 这是MySQL的默认隔离级别。在这个级别下,事务在整个过程中可以看到一致的快照数据,从而防止了不可重复读。

串行化(Serializable)

  • 这是最高的隔离级别。在此级别下,事务会进行全表锁定,从而防止了脏读、不可重复读和幻读,但可能会大大降低数据库操作的并发性能。

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

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

相关文章

Android设计模式--享元模式

水不激不跃,人不激不奋 一,定义 使用共享对象可有效地支持大量的细粒度的对象 享元模式是对象池的一种实现,用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象…

Qt项目打包发布超详细教程

https://blog.csdn.net/qq_45491628/article/details/129091320

HTML网站稳定性状态监控平台源码

这是一款网站稳定性状态监控平台源码,它基于UptimeRobot接口进行开发。当您的网站遇到故障时,该平台能够通过邮件或短信通知您。下面是对安装过程的详细说明: 安装步骤 将源码上传至您的主机或服务器,并进行解压操作。 在Uptim…

自动化测试中几种常见验证码的处理方式及如何实现?

UI自动化测试时,需要对验证码进行识别处理,有很多方式,每种方式都有自己的特点,以下是一些常用处理方法,仅供参考。 1 去掉验证码 从自动化的本质上来讲,主要是提升测试效率等,但是为了去研究验…

【点云surface】 修剪B样条曲线拟合

1 介绍 Fitting trimmed B-splines(修剪B样条曲线拟合)是一种用于对给定的点云数据进行曲线拟合的算法。该算法使用B样条曲线模型来逼近给定的点云数据,并通过对模型进行修剪来提高拟合的精度和准确性。 B样条曲线是一种常用的曲线表示方法…

【element优化经验】el-dialog修改title样式

目录 前言 解决之路 1.把默认的这个图标隐藏,官方的api有这个属性:showClose值设置false. 2.title插槽定制:左边定制标题,右边定制按钮区域。 3.背景颜色修改:默认title是有padding的需要把它重写调,然…

基于 STM32Cube.AI 的嵌入式人脸识别算法实现

本文介绍了如何使用 STM32Cube.AI 工具开发嵌入式人脸识别算法。首先,我们将简要介绍 STM32Cube.AI 工具和 STM32F系列单片机的特点。接下来,我们将详细讨论如何使用 STM32Cube.AI 工具链和相关库来进行人脸识别算法的开发和优化。最后,我们提…

Netty实现websocket且实现url传参的两种方式(源码分析)

1、先构建基本的netty框架 再下面的代码中我构建了一个最基本的netty实现websocket的框架,其他个性化部分再自行添加。 Slf4j public class TeacherServer {public void teacherStart(int port) throws InterruptedException {NioEventLoopGroup boss new NioEve…

Day40力扣打卡

打卡记录 包子凑数(裴蜀定理 DP) 根据裴蜀定理,存在 c gcd(a, b) 使不定方程ax by c满足条件,如果gcd(a, b) 1即a与b互素的情况下,就会 ax by 1,由于为1可以构造后面的无穷数字,故得到结…

Centos7 离线安装 CDH7.1.7

1. 安装CDH的准备工作(所有节点都要执行) 1.1 准备环境 角色 IP k8s-master 192.168.181.129 k8s-node1 192.168.181.130 k8s-node2 192.168.181.131 1.2 安装JDK # https://www.oracle.com/java/technologies/downloads/#java11 wget rpm -ivh…

亚马逊Listing怎么写!亲身经验分享

亚马逊运营的重要环节之一,listing的攥写,可以决定了产品的搜索排名,用户的点击率和转化率,那么如果你的产品排名或者转化不理想的情况,可以考虑对listing进行优化,在关键词过多和语句流程通顺的情况下&…

js获取时间日期

目录 Date 对象 1. 获取当前时间 2. 获取特定日期时间 Date 对象的方法 1. 获取各种日期时间组件 2. 获取星期几 3. 获取时间戳 格式化日期时间 1. 使用 toLocaleString() 方法 2. 使用第三方库 UNIX 时间戳 内部表示 时区 Date 对象 JavaScript中内置的 Date 对象…

数据挖掘之PCA-主成分分析

PCA的用处:找出反应数据中最大变差的投影(就是拉的最开)。 在减少需要分析的指标同时,尽量减少原指标包含信息的损失,以达到对所收集数据进行全面分析的目的 但是什么时候信息保留的最多呢?具体一点&#…

​飞凌嵌入式FCU2601网关,为工商业储能EMS注入智慧的力量

一、火热的储能行业,寻求新的市场机会 最近一段时间以来,世界储能大会、上海储能展、能源电子产业发展大会等多个储能相关论坛和展览密集登场,即使“内卷”已成为了业内讨论的热词,但寻求新的市场机会仍然是行业共识,…

Qt C++中调用python,并将软件打包发布,python含第三方依赖

工作中遇到qt c调用我的python 代码,并且想要一键打包,这里我根据参考的以及个人实践的结果来简单实现一下。 环境:windows系统,QT Creater 4.5, python 3.8(anaconda虚拟环境) 1. 简单QT调用…

electron windows robotjs 安装教程

Robotjs 安装 前言第一步 : 安装python第二步 : 安装Visual Studio 2022第三步 : 安装robotjs 前言 robotjs可以控制鼠标键盘,获取屏幕内容,配合electron可做很多自动化操作。windows下配置环境有很多坑,很多文章都太旧了。试了很多次发现了…

ky10 server x86 auditd安装(日志审计系统)

概述 Auditd工具可以帮助运维人员审计Linux,分析发生在系统中的发生的事情。Linux 内核有用日志记录事件的能力,包括记录系统调用和文件访问。管理员可以检查这些日志,确定是否存在安全漏洞(如多次失败的登录尝试,或者…

golang学习笔记——接口和继承比较2

接口和继承 现在有一个需要要求大学生和足球运动员掌握英语技能,请问怎么实现? 给运动员和学生结构体添加studyEnglish方法显示是可以的,但是篮球动员和中学生也学习了英语,显示不行。这时,我们可以直接给足球运动员和大学生添加…

跳转应用市场详情页market

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、跳转到各大厂商应…

播放器开发(四):多线程解复用与解码模块实现

学习课题:逐步构建开发播放器【QT5 FFmpeg6 SDL2】 前言 根据第一章内容,我们首先可以先把解复用和解码模块完成,其中需要使用到多线程以及队列,还需要使用FFmpeg进行解复用和解码动作的实现。 创建BaseQueue基类 BaseQueue.h…