MySQL中的索引和事务 (数据库系列5)

news2024/11/18 11:23:37

目录

前言:

1.索引

1.1 索引的概念

1.2索引的作用

1.3索引的使用场景

1.4索引的使用

1.4.1查看索引

1.4.2创建索引

1.4.3删除索引

1.5索引背后的数据结构 

1.5.1 B-树

1.5.2 B+树

2.事务

2.1事务的概念

2.2数据库事务的四个特性

2.2.1原子性

2.2.2一致性

2.2.3持久性

2.2.4隔离性

3.并发执行事务所引起的问题

3.1脏读问题

3.2不可重复读

3.3幻读

3.4三种问题的总结

结束语:


前言:

1.索引

1.1 索引的概念

索引是一种特殊的文件,包含着对数据表里所有记录的引用指针,可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。大家可以直接将索引理解为一本书里的目录。

1.2索引的作用

  • 数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
  • 索引所引起的作用类似书籍目录,可用于快速定位,检索数据。
  • 索引对于提高数据库的性能有很大的帮助。

其实索引存在的意义就是为了加快查找速度!!!

但是要注意的是查找速度是快了,但是付出了一定的代价,他需要付出额外的空间代价来保存索引数据,而且索引可能会拖慢新增、删除和修改的速度。

1.3索引的使用场景

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

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

满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。

反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。

1.4索引的使用

1.4.1查看索引

语法:

show index from 表名;

案例演示:

这里我们可以看到他是根据id来创建索引的,这里小编给大家说一下为什么我们还没有创建索引呢,他就显示已经有一个索引了,其实当我们在创建表的时候我会指定一些主键约束(primary key)、唯一约束(union)、外键约束(foreign key)时,就会自动创建对应列的索引。

由于我们student表中id是主键所以会给我们自动创建索引。

1.4.2创建索引

语法:

crate index 索引名 on 表名(列名);

案例演示: 

我们下面来根据student表中的name列来创建出一个索引。

注意:
小编这里又要强调了,创建索引危险系数很高!!!如果表里的数据很大,这个建立索引的开销就会很大!!!

1.4.3删除索引

 语法:

drop index 索引名 on 表名;

案例演示:

删除之后我们再次查看索引的时候就只剩下我们最初的那个索引了。当然了这里删除索引的操作也是非常危险的操作!!!大家一定要慎重。 

1.5索引背后的数据结构 

到这里相信大家对索引或多或少都有了一定的了解了,那么这里大家一起来和小编思考一个问题,我们之前学习数据结构的时候学习了很多中查询,其中有哈希表和二叉搜索树,这里有些同学就猜那么我们这里的索引背后是不是就是他两个其中的一个呢?这里小编个大家明确一点,不是!!!哈希表虽然查询速度快,但是它不支持范围查询,不支持模糊匹配;二叉搜索树如果元素个数多了,树的高度就会比较高,树的高度高了相对于比较次数来说就多了,对于数据库来说,则是IO访问次数,他就会多次访问硬盘;所以就都不太建议使用这两者。 那么我们又是用什么方法来组织索引的呢?这里我们来学习一种新的数据结构叫B+树。

首先在学习B+树之前我们先来了解一下B-树,这里小编给大家说一下这个B-树的读音他不读B树,而是读作B树,此处的-是“连接符”,不是减号!!!切记不能读错了,那么接下来小编就带着大家一起来看一下这个B-树到底是啥吧!

1.5.1 B-树

我们之前学习了一种树叫做二叉树相信大部分同学都还记得二叉树的特点,那就是树的度为二的就叫二叉树。那么我们这里的B-树是一个怎样的树呢?我们可以理解B-树就是一颗N叉搜索树,如果还不能理解的同学看一下下面的这张图相信大家很快就可以理解了。

我们在每一个结点中保存的值都是父结点的两个值之间的范围。此时我们会发现B-树的一个好处就是相比起二叉搜索树来说她的高度降低了很多,树的高度越高,进行查询的时候访问磁盘的次数就会越多,反之就会越少。所以这样的数据结构就会大大降低我访问磁盘的次数,从而有效的达到了搜索的效果。那么什么又是B+树呢?他与B-树有什么区别呢?我接着往下看。 

1.5.2 B+树

其实B+树就是B-树的一个改进,它也是一个N叉搜索树。但是与B-树的不同点在于整个树的所有数据都是包含在叶子节点中的,所有非叶子节点中的key都会出现在叶子节点中。我们看一下下面B+树的示意图:

而且它的叶子结点之间会连接在一起的,就像是一个列表一样将每个叶子结点都给串了起来。

B+树的特点:

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

这里小编来给大家解释一下B+树的最后一个特点的意思。

如果我们现在有一个student表,里面存储了一些值,如下所示:

那么在我们的叶子节点中就会存储每一条记录的具体数据,而父结点处只是简单的存储一些key值值本身即可,比如我们这里的id值。 

那么有同学有好奇了,我们上面如果不只有一个主键值呢?那么我们在查询的时候该怎么查询,这里我们表的数据还是会按照id为主键,构建出B+树,通过叶子节点组织所有的数据行,其次,针对name这一列,会构建出另一个B+树,但是这个B+树的叶子节点就不再存放这一行的完整数据了,而是存放这个主键id是啥,此时,如果你根据name来查询,查到叶子节点得到的只是主键id,我们还需要再次通过主键id来去主键id所构造出来的B+树上查询。这里我们就相当于查询了两次B+树。上述的这个过程我们称之为“回表”,这个过程都是MySQL自动完成的,用户是感知不到的。

B+树的优势:

  • 当前一个节点保存更多的key,最终树的高度是相对更矮的,查询的时候减少了IO访问次数。(和B树是一样的)
  • 所有的查询最终都会落到叶子节点上,此时我们查询任何数据,经过的IO访问次数都是一样的。这样就保证了稳定性。(这个稳定性对于程序员来说是很关键的,稳定能够让程序猿对于程序的执行效率有一个更准确的评估)
  • B+树的所有叶子节点,构成链表,此时比较方便进行范围查询。
  • 由于数据都在叶子节点上,非叶子节点只是存储了key值,导致非叶子节点占用的空间是比较小的,这些非叶子节点就可能在内存中缓存(或者是缓存了一部分),又进一步的减少了IO的次数。

上述的B+树就是我们MySQL组织数据的方式,当你看到一张“表”的时候实际上这个表不一定就是按照“表格”的这样的数据结构在硬盘上组织的,也有可能是按照这中树形结构组织的。这里具体的组织方式我们就不做过多的讨论了。 

2.事务

2.1事务的概念

我们先来看一个例子,如果有一天A要给B转账5000元,当A的账户这边转完之后A这边的用户余额就会扣掉5000元,但是呢在转的过程中突然我们的系统出现了Bug或者是突然断电了,结果导致B这边就没有收到这笔转账5000元的记录,这样A这边的余额减少了5000元,B这边的余额却没有增加一点,这件事显然是不符合我们的转账逻辑的。那么为了解决上述的问题我们就引入了事务这样一个概念,事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败其实事务的本质就是把多个SQL语句打包成一个整体,要么全部执行成功,要么就一个都不执行,而不会出现执行一半这种中间状态。在不同的环境中,都可以有事务,对应在数据库中,就是数据库事务。

2.2数据库事务的四个特性

2.2.1原子性

什么是事务的原子性呢?过去人们认为原子是事物能够分割的最小单位,所以就以原子来说明事务是不可分割的单位了。这也就对应了事务被打包成一个整体要么被全部执行,要么一个都不执行,不会出现执行一部分的情况。其中原子性是我们事务最核心的特性。

2.2.2一致性

事务的一致性是指,事务在执行前和执行后数据是可靠的,例如A给B转账5000,如果B这边收到的是5000元说明是可靠的,如果说收到的不是5000,那么这个事务就是一个不可靠的,没有保证事务的一致性。

2.2.3持久性

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

2.2.4隔离性

事务的隔离性是指,这个事务为了解决“并发”执行事务所引起的问题,它存在的意义就是为了在数据库并发处理事务的时候不会有问题(即是是有问题,也不会太大)

这里我们又引出了一个新的概念叫做并发。何为并发呢?并发就是指客户端给服务器发出了多份请求,此时服务器同时处理多个客户端发来的请求就是并发。我们可以举个栗子来理解一下:比如此时服务器就是一家餐馆,客户端就是来这家饭店的客人,此时一个餐馆(服务器)要同时给多个顾客(客户端)提供服务,如果餐馆处理这些顾客的要求时是一起处理的,那么此时就是“并发执行”。针对于我们所用到的数据库也是服务器,就可能有多个客户端都给服务器提交事务,数据库此时就需要并发处理多个事务。如果并发这些事务是修改不同的表/不同的数据,那就没有啥问题,但是如果修改的是同一个表/同一个数据,那就可能会带来一些问题!!!让我们接着往下看吧!

3.并发执行事务所引起的问题

注意:这里下面的所有问题都是由于事务“并发”执行所引起的问题!!!

3.1脏读问题

这里我们为了方便大家理解,给大家举一个例子:

比如我们的A在办公室里面对着电脑在写代码中,结果写着写着后面就飘过去了一个B,B此时就瞄了一眼A的写的代码,看自己可以有啥可以用到的代码,此时B在A的电脑屏幕上看到A写了这样的一段代码:class Student,并且有一些属性(id,name....),然后B就走了,结果就在B刚刚走之后A就修改了代码,他觉得自己写的代码也有点问题,然后就将刚刚代码增加了一些属性,此时B的读操作就是脏读,读到的数据也称之为“脏数据”,此处的“脏”的意思是指无效的意思。

那么为了解决这一问题,我们就想了一个办法在MySQL中引入了一个“写操作加锁”这样的机制,也就是A和B约定好了在A写代码的时候B不允许来瞄A的代码,也就相当于上厕所的时候锁门这样的操作。

注意:

但是给写操作加锁之后也就意味着写操作和读操作不能同时进行了,也就是我们上述所谈论到的这两个操作不能“并发”执行了。此时这个写操作就降低了并发程度(降低了效率),但是同时也提高了隔离性(提高了数据的准确性)!!!

3.2不可重复读

此时我们依旧是A和B两个同事在办公中,此时是二人已经约定好了当A在写代码的时候,B不可以进行读代码,也就是给写加锁,此时A写好代码之后提交到了Gitee上面,然后B就去Gitee上面去读取代码,但是就在B读取的过程中,A发现他有一段代码写的有点问题,重新修改后就又一次上传了Gitee,此时B读着读着,结果一下子代码刷~的一下就变样了,此时B读出来的结果可能就不一样了,像这样的问题我们就称之为不可重复读。

为了解决这一个问题A和B就签订了一个协议:在B读取代码的时候A是不可以修改代码的,此时就是给读进行了加锁。在A写的时候B不可看是给写加锁,此时B在读的时候不能看是给读加锁。

注意:
通过这个“读加锁”操作,又进一步的降低了事务并发处理的能力(处理事务效率也降低了),提高了事务的隔离性(数据的准确性又提高了)!!!

3.3幻读

但是当我们给“写加锁”和“读加锁”这样就可以保证万无一失了吗?当然不是,前面给“写加锁”和“读加锁”已经解决了脏读和不可重复读的问题,但是如果A在此时不在原有的代码上面进行改动,而是新写了一个.java文件呢?比如之前A写了Student.java文件然后上传至Gitee上面了,B去读了Student.java里面的内容,结果A在B读的过程中又写了Teacher.java文件,然后又上传到了Gitee中。此时B在读取的时候突然就发现代码中怎么又多出来一个Teacher.java文件了,也就是在“读加锁”和“写加锁”的前提下,一个事务在两次读取数据的时候,发现数据的值是一样的,但是结果集不一样了,就比如B在第一次读取的时候是只有(Student.java),结果在第二次读取的时候结果变成了(Student.java、Teacher.java)这就称之为“幻读”。

注意:

那么为了解决“幻读”问题,数据库中使用“串行化”来解决这个问题,也就是彻底放弃了“并发”处理事务,一个接着一个的处理事务,这样做,并发程度是最低的(效率最慢),隔离性是最高的(数据的准确性也是最高的)!!!

3.4三种问题的总结

出现的问题操作结果效果
给写加锁(read uncommitted)没有进行任何锁限制并发程度最高(效果最高),隔离性最低(准确性最低)
脏读给读加锁(read committed)给写加锁了

并发程度降低,隔离性提高了

不可重复读repeatable read给写和读都加锁了

并发程度又降低了,隔离性又提高了

幻读serializable串行化

并发程度最低,隔离性最高 

结束语:

好了这节有关于索引和事务的一些基础知识小编就介绍到这里啦!如果还是没有理解的同学建议下去之后多多联想一下现实生活中的例子来帮助自己更好的理解此处的知识点,大家继续跟紧小编的步伐,一起往前冲!!!希望这节对大家认识数据库有一定的帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

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

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

相关文章

城会玩,Selenium+Docker成功解决这一大难题

01、需求背景 日常测试中会遇到对web应用进行UI自动化的测试场景,一般常用的工具是使用Selenium,一套简单的UI自动化架构如下: 上图即为简单搭建的一套UI自动化测试架构,但 串行执行测试用例: 一台机器只能安装一个…

《英雄联盟》提示丢失D3DCompiler_43.dll的三个解决方法

在我们打开游戏《英雄联盟》的时候,计算机报错提示“由于找不到D3DCompiler_43.dll,无法继续执行此代码”,“D3DCompiler_43.dll丢失”是怎么回事呢?D3DCompiler_43.dll是一个Microsoft DirectX的组件文件,它是用于编译…

博客系统(使用前后端分离)

博客系统 前言一.准备工作1.1 准备好前端文件1.2 设计数据库1.3 编写基本的数据库代码1.4 封装好数据库的连接操作1.5 根据设计的表创建实体类1.6 根据实体类,提供一些简单的增删改查操作 二.博客要实现的功能2.1 博客列表页功能2.2 博客详情页2.3 博客登录页2.4 页面强制登录功…

涵子来信——AI的无限未来——谈谈想法

大家好: 这一次,我想要跟大家讲一讲我对AI的看法和未来的展望,谈谈我的想法。 AI(Artificial Intelligence,中文人工智能),是我们生活中处处都可以见到的,小到一个语音助手&#x…

ylb-接口13实名认证

总览: 在api模块下的service包,创建一个充值接口RechargeService,并创建一个(根据userID查询它的充值记录)方法: package com.bjpowernode.api.service;import com.bjpowernode.api.model.RechargeRecord…

迪赛智慧数——柱状图(多色柱状图):旅行灵感来源

效果图 涉足旅行就是一次睿智的选择,心系未来、永不停步,让精神和思维得到滋养,更加懂得珍惜和感恩,这是旅行给予生活的灵感。西方一位哲人也说过,“生命的意义在于尝试,体验不同的可能”,旅行能…

基于springboot+Redis的前后端分离项目(九)-【黑马点评】

🎁🎁资源文件分享 链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA?pwdeh11 提取码:eh11 附近的商户、用户签到、UV统计 (一)附近的商户1.附近商户-GEO数据结构的基本用法2.附近商户-导入店铺数据到…

Python实现登陆界面+生日界面

文章目录 1. 需求分析1.1 功能分析1.2 性能分析 2. 技术原理3. 详细设计3.1 登录界面3.2 注册界面3.3 修改密码3.4 注销账户3.5 生日界面 4. 功能实现4.1 登陆界面4.2 注册界面4.3 修改密码4.4 注销账户4.5 生日界面 1. 需求分析 1.1 功能分析 ① 登录界面实现用户的登录、注…

消费者行为分析VR情景模拟演练系统

VR虚拟现实技术是一种先进的技术,利用VR开展消费者行为分析课程是一种创新的教育方式,它可以提高学生的学习兴趣和效果,同时也可以为企业提供更好的人才培训和发展机会。 1.帮助学生更好地理解和应用心理学概念:VR技术可以让学生…

【Vite搭建Vue3项目】如何使用自定义的svg

Vite搭建Vue3项目如何使用自定义的svg 1. 准备一份svg图标集放入到自己想放的目录2. 下载对应的插件并进行配置3. 测试使用 绪论:当用 vite 构建 vue3 项目的时候,咱可以使用 Element-plus 为我们提供的图标,但是它是一个个标签,当…

HTTP1.1 wireshark分析

本地springboot启动一个简单的服务,然后请求测试 tcpdump -i lo0 -nnvv -w tmp.cap tcpdump 本地回环网卡 http1.1 HTTP/1.0 每进行一次通信,都需要经历建立连接、传输数据和断开连接三个阶段。当一个页面引用了较多的外部文件时,这个建立…

两种异步日志方案的介绍

文章目录 一、日志写入逻辑1.1 相关接口函数1.2 写入逻辑 二、log4cpp 日志框架2.1 下载和编译2.2 日志级别2.3 日志格式2.4 日志输出2.5 日志回滚 三、muduo 异步日志库3.1 异步日志机制3.2 双缓冲机制3.3 前端日志写入3.4 后端日志落盘3.5 coredump 查找未落盘的日志3.6 总结…

复习第六课 C语言-排序,初识指针

目录 【1】冒泡排序&#xff08;从小到大&#xff09; 【2】选择排序 【3】二维数组 【4】指针 【5】指针修饰 【6】大小端 【7】初见二级指针 练习&#xff1a; 【1】冒泡排序&#xff08;从小到大&#xff09; #include <stdio.h> //数组哪里的\0?自己和字符串…

论文阅读-2:基于深度学习的大尺度遥感图像建筑物分割研究

一、该网络中采用了上下文信息捕获模块。通过扩大感受野&#xff0c;在保留细节信息的同时&#xff0c;在中心部分进行多尺度特征的融合&#xff0c;缓解了传统算法中细节信息丢失的问题&#xff1b;通过自适应地融合局部语义特征&#xff0c;该网络在空间特征和通道特征之间建…

SSH框架简介篇

文章目录 概述目录结构 strutsSpringHibernate总结 概述 SSH框架&#xff08;Struts Spring Hibernate&#xff09;是一种广泛应用的Java企业级开发框架组合&#xff0c;它将Struts、Spring和Hibernate三个优秀的框架有机地结合在一起&#xff0c;提供了一套完整的解决方案&…

cmake 函数相关

目录 cmake函数和宏基础 demo cmake函数和宏的参数处理 cmake函数和宏的基本使用 demo cmake函数和宏使用变量 demo demo cmake函数和宏需要注意的地方 demo cmake函数和宏的关键字参数 demo 使用第二种形式cmake_parse_arguments() demo 关键字list demo singl…

GDB 调试代码

目录 一、其他调试代码的工具 二、GDB调试 1、调试准备 2、开始调试 3、调试命令 1.运行程序 2.退出gdb 3.传参 4.查看代码 5.设置或删除断点及相关操作 6.继续运行 7.运行中打印某些值及其类型 8.自动的打印某些值和信息及其相关操作 9.单步调试 10.设置变量的…

http-server 的安装与使用

文章目录 问题背景http-server简介安装nodejs安装http-server开启http服务http-server参数 问题背景 打开一个文档默认使用file协议打开&#xff0c;不能发送ajax请求&#xff0c;只能使用http协议才能请求资源&#xff0c;所以此时我们需要在本地建立一个http服务&#xff0c…

基于java的智能停车场管理系统

背景 智能停车场管理系统的主要使用者分为管理员和用户&#xff0c;实现功能包括管理员&#xff1a;个人中心、用户管理、车位信息管理、车位租用管理、车位退租管理、违规举报管理、论坛交流、系统管理&#xff0c;用户&#xff1a;个人中心、车位租用管理、车位退租管理、违…

MySQL每日一练——MySQL多表查询进阶挑战

目录 1、首先创建表 t_dept: t_emp: 2、插入数据 t_dept表&#xff1a; t_tmp表: 3、修改表 4、按条件查找 1、首先创建表 t_dept: CREATE TABLE t_dept (id INT(11) NOT NULL AUTO_INCREMENT,deptName VARCHAR(30) DEFAULT NULL,address VARCHAR(40) DEFAULT NULL,P…