开开心心带你学习MySQL数据库之第八篇

news2025/1/24 14:56:08

在这里插入图片描述

索引和事务
~~ 数据库运行的原理知识 + 面试题

索引

索引(index) => 目录
索引存在的意义,就是为了加快查找速度!!(省略了遍历的过程)
查找速度是快了,但是付出了一定的代价!!
1.需要付出额外的空间代价来保存索引数据
2.索引可能会拖慢新增,删除,修改的速度
~~ 以写小论文为例
论文最前面要生成目录(word,能自动生成目录)
如果word没有这个功能,手动维护,一定会非常麻烦的

整体来说,还是认为索引是利大于弊的~~
实际开发中,查询场景一般要比增删改频率高很多!!!

索引的使用

~~ 查看索引
show index from 表名;

~~ 创建索引
create index 索引名 on 表名(列名);
创建主键约束(PRIMARY KEY),唯一约束(UNIQUE),外键约束(FOREIGN KEY)时,会自动创建对应列的索引
创建索引操作,可能很危险!!!
如果表里的数据很大, 这个建立索引的开销也会很大!!!
比如有一本很厚的书,现在让你给这个书手动的弄一份目录出来~~ 工作量巨大
~~ 好的做法,是创建表之初就把索引设定好
~~ 如果表里已经有很多数据,索引就别动了

~~ 删除索引
drop index 索引名 on 表名;
和创建索引类似,删除索引也可能存在风险!!!

探索索引背后的数据结构

可以用来加快查询的数据结构?
~~ 二叉搜索树
~~ 哈希表
实际上, MySQL并非使用以上的两个数据结构
原因:
二叉搜索树 => 如果元素个数多了,树的高度就会比较高~~ 树的高度相当于比较次数,对于数据库来说,则是IO访问次数,数据库里的数据在硬盘上.
哈希表 => 哈希表虽然查询的快,但是不能支持范围查询,也不能支持模糊匹配
B+ 树 => 索引的关键结构 ~~为了数据库索引,量身定做的数据结构

B+ 树
先了解B树,再来了解B+ 树

B树

B树,也叫做B-树~~ 此处–是“连接符",不是减号!!!千万不要念成B减树
B树可以认为是一个N叉搜索树,与二叉搜索树(二叉搜索树的度为2)进行类比了解
树的度 => 所有节点的度的最大值~~ 节点的度是有几个孩子(孩子节点个数)

在这里插入图片描述

当节点的子树多了,节点上保存的key多了意味着在同样key 的个数的前提下B 树的高度就要比二叉搜索树低很多!!
树的高度越高,进行查询比较的时候访问磁盘的次数就越多!!!效率就越低了

B+ 树

B+ 树,在B树的基础上又做出改进 ~~(也是N叉搜索树)
在这里插入图片描述

B+树的特点
1.一个节点,可以存储N个key,N个key划分出了N个区间~~(而不是N+1个区间).
2.每个节点中的 key 的值,都会在子节点中也存在(同时该key是子节点的最大值).
3.B+树的叶子节点,是首尾相连,类似于一个链表.
~~ 由于B+树特点1,2,3导致整个树的所有数据都是包含在叶子节点中的,(所有非叶子节点中的key最终都会出现在叶子节点中).
4.由于叶子节点,是完整的数据集合,只在叶子节点这里存储数据表的每一行的数据.而非叶子节点,只存key值本身即可.

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

如果这个表里有多个索引呢?针对id有主键索引,针对name又有一个索引表的数据
~~ 还是按照id 为主键,构建出B+树通过叶子节点组织所有的数据行
~~ 其次,针对 name 这一列,会构建另外一个B+树但是这个B+树的叶子节点就不再存储这一行的完整数据,而是存主键id 是啥
~~ 此时,如果你根据 name 来查询,查到叶子节点得到的只是主键 id,还需要再通过主键 id 去主键的B+树里再查一次~~ (查两次B+树)
(上述过程称为"回表",这个过程,都是MySQL 自动完成的,用户感知不到)

面试八股文
~~对于实际工作,用处不大(工作中不会让你实现一个B+树的),但是面试老考(只能尽量掌握)

事务

经典场景: 转账
account(id, balance)
id balance
1 1000
2 0
1给2转账500
步骤:
1)update account set balance = balance - 500 where id = 1;
2)update account set balance = balance + 500 where id = 2;
假设,在执行转账过程中,执行完1之后,数据库崩溃了/主机宕机此时这个转账就僵硬了!
~~ 1的钱扣了,但是2的钱没到账!
事务就是为了解决上述的问题
~~ 事务的本质就是把多个sqI 语句给打包成一个整体
~~ 要么全都执行成功,要么就一个都不执行,而不会出现"执行一半"这样的中间状态!!!

淘宝买东西~~ 下单
~~ 下订单的同时,要进行支付
~~ 你这边账户扣钱了,同时订单表中也会生成一个对应的数据

“把多个sqI 语句给打包成一个整体” => 事务的原子性(atom) => 计算机中不可分割的基本单位
“一个都不执行” => 不是真的没执行,而是"看起来好像没执行一样" => 具体是执行了,执行一半出错了,出错之后,选择了恢复现场,把数据还原成未执行之前的状态了,类似于ctrl+z ~~ 这个恢复数据的操作,称为“回滚" (rollback)

进行回滚的时候,是怎么知道回滚是恢复到啥样的状态呢??
此处是需要额外的部分来记录事务中的操作步骤(数据库里专门有个用来记录事务的日志)
正因为如此,使用事务的时候,执行sql的开销是更大的,效率是更低的!!!
~~ 只要是执行失败,都会触发回滚

使用

(1)开启事务:start transaction;
(2)执行多条SQL语句;
(3)回滚或提交:rollback/commit;
注:rollback即是全部失败,commit即是全部成功

-- 开启事务
start transaction;

-- 中间就是要执行的每一步操作
update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;

-- 提交事务,到这一步,相当于事务就执行完了
commit;

事务使用起来容易,理解起来困难
⭐️⭐️⭐️数据库的事务,有四个关键的特性(面试八股文,~~ 经典面试题):
1.原子性~~ (事务最核心的特性)~~ 事务的初心
2.一致性~~ 事务执行前后,数据得是靠谱的 ~~
3.持久性~~ 事务修改的内容是写到硬盘上的,持久存在的,重启也不丢失
4.隔离性⭐️⭐️⭐️⭐️⭐️
~~ 这个隔离性是为了解决"并发"执行事务,引起的问题
例子:一个餐馆(服务器),同一时刻要给多个顾客(客户端)提供服务
这些顾客提出的请求,是"一个接一个"的来的嘛?还是一股脑一起来了一波?? => 都有可能
“一股脑一起来了一波“ => 此时,服务器同时处理多个客户端的请求,就称为“并发"(齐头并进的感觉)
~~ 数据库也是服务器,就有可能多个客户端都给服务器提交事务
~~ 数据库就需要并发的处理多个事务
~~ 如果并发的这些事务,是修改不同的表/不同的数据,没啥事~~
~~ 如果修改的是同一个表/同一个数据 => 可能会带来一定的问题的!!!~~
~~ 比如多个客户端一起尝试对同一个账户进行转账操作,此时就可能会把这个数据给搞乱了
事务的隔离性,存在的意义就是为了在数据库并发处理事务的时候不会有问题(即使有问题,问题也不大)
那么并发处理事务,可能会有哪些问题.以及这些问题数据库的隔离性是怎样解决的~~ (挺麻烦的)

并发执行事务可能产生的问题
—.脏读问题

场景: 我在图书馆写代码(上课要交的作业),在我写的过程中,有一个同班同学,在我身后经过,他喵了一眼我的屏幕~~ 看到了我的代码中写了一些内容,然后他就走了~~ 他走了之后,可能会出现~~ 我发现我的代码写的有问题,不符合题意,又改了~~ 又或者我写的代码没有问题,又没改.
一个事务A正在对数据进行修改的过程中,还没提交之前,另外一个事务B,也对同一个数据进行了读取.此时B的读操作就称为“脏读",读到的数据也称为“脏数据”~~ 脏的意思,是"无效",不是埋汰的意思.
~~ 为啥说无效?很可能,A回头又把数据给改了.

为了解决脏读问题, mysql 引入"写操作加锁"这样的机制
大概场景就是: 我和同学商量好~~ 我写代码的过程中,你别来看~~ 等我改完,提交到码云上,你再通过我的码云来看 => 写的时候不能看(给写操作加锁),写完了才能看.
当我写的时候,同学没法读,意味着我的"写操作"和同学的"读操作"不能并发了~~(不能同时执行了).
这个给写加锁操作,就降低了并发程度(降低了效率),提高了隔离性(提高了数据的准确性).

二.不可重复读

还是我写代码,同学想看一看怎么做
~~ 约定好,我写的时候,不许看,等我提交了,再通过码云来看(约定好写加锁了)
~~ 我写代码,提交了版本1.此时就有同学开始读这个代码了
~~ 突然发现题目还存在更优解,于是我又打开代码,继续修改代码,然后又提交版本2
~~ 这个同学开始读的过程中,读到的是版本1的代码,读着读着,我提交了版本2,此时这个同学读的代码,刷的一下变样了!!这个问题,叫做"不可重复读" => 第一次和第二次读到的结果不一样.
事务1已经提交了数据.此时事务2开始去读取数据.在读取过程中,事务3又提交了新的数据.
此时意味着同一个事务2之内,多次读数据,读出来的结果是不相同的~~ (预期是一个事务中,多次读取结果得一样)就叫做"不可重复读”~~ 第二次读取的结果不能复现第一次的结果 => 好比看微信余额,第一次看一眼,发现余额是这些,过几秒啥也没做再看一眼,第二次看一眼的时候,余额就变了,钱没了,这就出大问题了,必须确保两次查看时余额不变,才符合现实生活.
~~ 同学发现了这个问题之后,知道了是在他读的过程中,我又改代码了,于是来找我,和我约定
~~ 他/她读代码的时候,我也不能修改!!!
~~ 刚才约定的是,我修改的时侯,提交之前,同学不要读,是给写加锁
~~ 现在是约定,同学读的时候,我不能修改,就是给读加锁
~~ 在同学读完了之后,我就可以修改了,即加锁之后就会进行解锁
通过这个读加锁,又进一步的降低了事务的并发处理能力(处理效率也降低了),提高了事务的隔离性(数据的准确性又提高了)

三.幻读

当前已经约定了读加锁和写加锁,解决了不可重复读和脏读问题
由于约定了读加锁,同学读的时候,我不能改代码了
~~ 我在这干的等着??光摸鱼打王者,有点难受(主要是玩这游戏,输多赢少,本就不太爱玩了,恰好又输了一把)
~~ 所以我想了办法,同学读Student.java,那好,我就创建一个Teacher.java,就写这个代码呗!!
~~ 这样的情况,大多数情况下都没事,少数情况下,个别同学发现了,读代码读着突然多出个Teacher.java这个文件,有的同学就觉得接收不了
在读加锁和写加锁的前提下,一个事务两次读取同一个数据,发现读取的数据值是一样的,但是结果集不一样
~~ (Studentjava 代码内容不变,但是第一次看到的是只有 Student.java 这个文件,第二次看到的是 Student.java 和Teacher.java 这两个文件了…),这种就称为"幻读’.

数据库使用"串行化"这样的方式来解决幻读.彻底放弃并发处理事务,一个接一个的串行的处理事务.这样做,并发程度是最低的(效率最慢的),隔离性是最高的(准确性也是最高的)
~~ 相当于是同学们要求,在他们读代码的时候,我不要摸电脑,必须强制摸鱼打王者!!

上述三个问题脏读,不可重复读,幻读就是并发处理事务的三个典型问题
对应上述问题, mysql提供了4种隔离级别,就对应上面的几个情况
以下是四种隔离级别

read uncommitted没有进行任何锁限制,并发最高(效率最高),隔离性最低(准确性低)
read committed给写加锁了,并发程度降低,隔离性提高了
repeatable read给写和读都加锁,并发程度又降低,隔离性又提高了
serializable串行化,并发程度最低,隔离性最高
脏读给写加锁read committed并发程度降低,隔离性提高了
不可重复读给读加锁repeatable read并发程度又降低,隔离性又提高了
幻读彻底串行化serializable并发程度最低,隔离性最高

四种隔离级别是mysqI 内置的机制,
~~ 可以通过修改mysqI的配置文件, 来设置当前 mysql 工作在哪种状态下

这几个隔离级别,如何选择???
~~ 这几个级别没有好坏,在准确性和效率之间进行权衡
~~ 看实际需求,看业务场景
~~ 转账的时候,一分钱都不能差,哪怕慢点,也得转对!!!此时准确性要拉满,效率不关键
~~ 抖音,点赞,一个视频有多少赞,要求快,赞的数量差个十个八个,都没事,此时追求的是效率,准确性就不关键
级别是mysqI 内置的机制,
~~ 可以通过修改mysqI的配置文件, 来设置当前 mysql 工作在哪种状态下

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

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

相关文章

信息系统项目管理师(第四版)教材精读思维导图-第十四章项目沟通管理

请参阅我的另一篇文章,综合介绍软考高项: 信息系统项目管理师(软考高项)备考总结_计算机技术与软件专业技术_铭记北宸的博客-CSDN博客 本章思维导图XMind源文件 14.1 管理基础 14.2 管理过程 14.3 规划沟通管理 14.4 管理沟通 14.…

机器学习:使用PCA简化数据

文章目录 使用场景主成分分析(Principal component analysis)实验:对半导体数据(590个特征)进行降维处理 使用场景 我们通过电视看实况足球,电视显示屏有100万个像素点,球所占的点数为100个。人…

Collectors类作用:

一、Collectors类: 1.1、Collectors介绍 Collectors类,是JDK1.8开始提供的一个的工具类,它专门用于对Stream操作流中的元素各种处理操作,Collectors类中提供了一些常用的方法,例如:toList()、toSet()、to…

真的有线上兼职吗?推荐几个靠谱的线上兼职!

在这个互联网普及,信息爆炸的时代,线上赚钱已经成为一个热门的话题。每个人都想通过互联网赚钱,有些人得到钱,给普通人机会,给骗子一些机会,世界是两面,线上兼职赚钱的方式!有好有坏…

python中的继承

要理解继承首先要有父类和子类的概念,可以理解成子类从父类中继承父类的属性和方法 创建父类 class Pet:def __init__(self,name,age):self.name nameself.age agedef jump(self):print(self.name"在跳")创建子类 class Cat(Pet):pass mycatCat(&quo…

HTML的有序列表、无序列表、自定义列表

目录 背景: 过程: 无序列表: 简介: 代码展示: 效果展示:​ 无序列表: 简介: 效果展示:​ 自定义列表: 简介: 效果展示: 总结: 背景: 1.有序列表(Ordered List): 有序列表是最早的列表类型之一&#xff…

编译器02-词法分析

一:简述 词法分析含义:为了翻译语言,编译器把程序各种成分拆开,那如何拆,首先第一步就是将输入分解成一个个独立的单词(token),这一过程叫词法分析。 二:单词(token)分为哪些种类 保留字…

类和对象:构造函数,析构函数与拷贝构造函数

1.类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器…

MAC M1芯片安装mounty读写移动硬盘中的文件

因为移动硬盘中的文件是微软公司NTFS格式,MAC只支持自己的APFS或者HFS,与微软的NTFS不兼容,所以需要第三方的软件来支持读写硬盘中的文件,经过一上午的折腾,最终选择安装mounty这个免费的第三方软件 工具网址连接&am…

C++11 类型转换

#include<iostream> #include<string> using namespace std;//类型转换 void Insert(size_t pos, char ch) {size_t _size 5;//....int end _size - 1;while (end > pos) // end隐式类型转换{//_str[end 1] _str[end];--end;} } void Test1() {int i 1;// …

C++:内存管理

目录 学习目标 1. C/C内存分布 2. C/C动态内存管理 2.1 C动态内存管理 2.2 C动态内存管理&#xff1a; 3. operator new与operator delete函数 4. new和delete的实现原理 5. 定位new表达式 学习目标 1. C/C内存分布 2. C/C动态内存管理&#xff08;malloc,free 与new ,…

【深度学习实战—6】:基于Pytorch的血细胞图像分类(通用型图像分类程序)

✨博客主页&#xff1a;米开朗琪罗~&#x1f388; ✨博主爱好&#xff1a;羽毛球&#x1f3f8; ✨年轻人要&#xff1a;Living for the moment&#xff08;活在当下&#xff09;&#xff01;&#x1f4aa; &#x1f3c6;推荐专栏&#xff1a;【图像处理】【千锤百炼Python】【深…

SQL Server2022版本 + SSMS安装教程(手把手安装教程)

SqlServer安装步骤如下&#xff1a; 下载请点点我 1.选择Developer版 2.点击浏览器下载标志&#xff0c;找到SqlServer在文件夹的位置。 3.进入下面的界面&#xff1a;选择自定义版本 4.将下载的C盘的盘符改为D盘 5.点击安装–进入下一步&#xff0c;显示如下界面。 过…

构建知识库的核心要义,试试我的工具和方法吧!

对于企业来说&#xff0c;如果所有人员的知识和经验&#xff0c;都集中沉淀到统一的文档系统中&#xff0c;那么&#xff0c;久而久之&#xff0c;会形成一个丰富的知识和经验库。 在构建知识库之前&#xff0c;我们要先确定知识库范围包含&#xff1a;素材整理、问题提炼、知识…

【Selenium】webdriver.ChromeOptions()官方文档参数

Google官方Chrome文档&#xff0c;在此记录一下 Chrome Flags for Tooling Many tools maintain a list of runtime flags for Chrome to configure the environment. This file is an attempt to document all chrome flags that are relevant to tools, automation, benchm…

7、Spring之依赖注入源码解析(下)

resolveDependency()实现 该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。 @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Null…

拦截器学习

什么是拦截器 Spring MVC 中的拦截器( Interceptor )类似于ServLet中的过滤器( Filter )&#xff0c;它主要用于拦截用户请求并作出相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。 工作原理 一个拦截器&#xff0c;只有 preHandle …

mac电脑安装paste教程以及重新安装软件后不能使用解决方法

问题背景 mac电脑安装paste教程以及重新安装软件后不能使用解决方法。 mac电脑安装paste失败&#xff0c;安装好后还是无法使用&#xff0c;paste显示还是历史粘贴信息&#xff0c;导致无法使用。新 copy的内容也无法进入历史粘贴版里面。 笔者电脑配置信息&#xff1a;MacB…

7.13 在SpringBoot中 正确使用Validation实现参数效验

文章目录 前言引入Maven依赖一、POST/PUT RequestBody参数校验1.1 Valid或Validated注解配合constraints注解1.2 测试运行 二、GET/DELETE RequestParam参数校验2.1 Validated注解配合constraints注解2.2 测试运行 三、GET 无注解参数校验3.1 Valid或Validated注解配合constrai…

【OpenCV • c++】直方图计算 | 绘制 H-S 直方图 | 绘制一维直方图 | 绘制 RGB 三色直方图

文章目录 一、什么是直方图二、直方图的相关函数1、计算直方图 calcHist()2、找寻最值 minMaxLoc() 三、程序演示1、色调 —— 饱和度直方图2、一维直方图3、RGB 三色直方图 一、什么是直方图 直方图广泛应用于很多计算机视觉处理当中。通过标记帧与帧之间显著的边缘和颜色的变…