牛马日志-存储引擎+索引+事务🤡

展示

作为一个平民作者,在文化的底层输出,卑微的记录自己的学习经历,在社会生活的压迫下,终于无法掩盖自己的脆弱(宇哥说我菜,我说他jb🤡)。

生而为人,必当思己之弊,优己之德才,以善对人,人言汝jb,汝不怒之也,独言一句:Shut up Fuck you!

下面开始正文,🐂🐴冲冲冲!

存储引擎

什么是存储引擎呢?

如果你此时此刻还不知道什么是存储引擎,那么说明你以前就不知道什么是存储引擎!🤡

一句透彻的分析,说出了🐂🐴们的实力,我们开始走入存储引擎,let,s go,苏喂苏喂苏喂!

sql 复制代码
Create Table: CREATE TABLE `engine_demo_table` (   `i` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8

建表的语句就可以选择存储引擎!

mysql底层存储数据的功能,负责存储数据、给数据建立索引、更新数据、查询数据,不同的存储引擎有不同的特点,我们只介绍比较常用的存储引擎里,最不常用的两个!😁

InnoDB

InnoDB是一个健壮的事务型存储引擎,他的特点是支持事务,可以支持行级锁🔐,外键约束(不一定用的到),支持自动增加列AUTO_INCREMENT属性,5.7开始InnoDB成为MySQL默认的存储引擎。

需要事务支持,有较高的并发读取频率,可以选择InnoDB存储引擎。

MyISAM

不太常用了,具体就是表级锁🔐,不支持外键,不支持事务,我们知道这些就行了,面试够用,谁还继续研究啊,那不是🐂🐴吗?

优缺点对比

锁机制不同:

表锁,即使操作一条记录也会锁住整个表,不适合高并发的操作

行锁,操作时只锁某一行,不 对其它行有影响,适合高并发 的操作

MyISAN只缓存索引,不缓存 真实数据

InnoDB不仅缓存索引还要缓存真实数 据,对内存要求较高,而且内 存大小对性能有决定性的影响

索引

为什么要使用索引

不使用索引找数据的时候,非常的耗时,就像你去图书馆找书,没有分类,这jb不是垃圾堆🐴

那我们如果使用二叉树来存储数据,是不是好多了,这就索引的意义所在,快速找到数据,并占有他😎

这个就是B+树的结构了,最下层是我们存储的数据,也就可以想象成表里的一条条数据组成的数据页,第二层是把每页最大的页码又重新进行分页了,第三层是又进行了一次分页,这样我们就能很快的找到想要的数据,而且大家要注意数据都是有顺序的,这样非常方便我们来进行排序查询语句,同时呢建立索引的数据,修改和删除会导致索引变动,造成底层的IO成本哦。

索引分为几种:

聚簇索引:

🐂🐴又要问了,这是什么宇哥🐢索引,没有听过啊!

当然了,菜鸟谁知道这个,知道这个,你还是菜鸟吗?你对的起这两个字🐴,来今天我们就从菜鸟迈入到垃圾的阵营里。

当你创建表的时候,用的是InnoDB存储引擎,那就会默认生成一个聚簇索引,默认按照主键去排序成一个顺序链表,采用B+树的数据结构来存储,如果没有主键呢(不加主键那么🐂B,你是宇哥🐢吗?),当然会选择一个唯一字段来进行排序,如果没有唯一字段就会默认生成一个隐藏主键字段去进行排序,这里有个小彩蛋了,主键自增可以加快效率奥,因为主键不是自增的没有规律,那就会产生不必要的IO操作。

二级索引

就是和聚簇索引一样的数据结构,区别在于数据页存储的是主键,需要回表才能拿到数据,也就是通过主键去聚簇索引拿到完整的数据,来下面看图👇🏻

这就很清楚了,我们二级索引底层是key(分页数)+pk(主键)。

这里提示大家通过主键去修改数据会比二级索引要快哦,因为省去了回表的操作!

联合索引

数据结构也是和二级索引差不多,只是多个字段进行B+树的方式来储存,区别在于,他会按照第一个字段进行优先排序,然后第一个字段相同,在进行第二个字段排序,这也就是我们常说的,前面的字段会生效的原因了。

MyISAM和InnoDB索引对比

MyISAM没有聚簇索引,都是二级索引,每次查询都需要回表,但是数据页里存储的是地址,回表非常快,没有聚簇索引,数据和索引是分离存储的。 InnoDB有聚簇索引,且是必须存在的,数据和索引是存储在一起的。

赠送小知识点,HASH结构

Hash结构就是类似key-Value的存储方式,把你要保存的数据,通过算法获取一个唯一结果,通过这个结果去查询、插入、删除,他的复杂度要更低是o(1),B+数需要从上向下一次查找。

还有就是hash结构的key计算后结果比如是17还有一个key是33,用取模16这种方式来找存储点可能是存储到一个位置,专业名词叫做"碰撞"💥,那这种情况怎么处理呢,这时我们会用链表的解决方式来处理,存储到相同位置的数据,用链表来存储。

问题来了Hash的速度快,我们为什么不用hash结构来存储数据呢?小🐂🐴你的问题超纲了您知道吗?
原因:

Hash结构能满足=、<>、in的查询,这样肯定查找效率更高,但是我们想如果来一个order by 兄弟们,hash是无序的啊!这可难办了?

🤠 我敲,难办就别办了,而且联合索引hash是不支持的,对于我们平时根据type=1这样范围的查找,hash也是非常慢的,如果用b+数,那不就飞快!

那hash结构怎么优秀我们是不是也要利用一下啊,InnoDB能就提供了这样一个功能,自适应Hash索引 ,当一个数据被经常使用,那么这个数据的地址,会被存储到Hash表里,这样我们在享受着B+树的福利上,也用到了Hash的特点真是:宇哥🐢去健身房吃炸鸡,什么都想要啊!

事务

先来个大家都懂的,也是面试比较常问的:说一下事务的四个特性?

一看这面试官挺在试探你呢,这个都过不了,兄弟们,此场面试,G已!

让我们把这个4个特性先背熟!!!

4个特性:

原子性:要么成功,要么失败,没有别的结果,联想记忆法来了!

原子性就等于原子弹啊,要么全部融化掉,要么就是投掷失败,没有别的选择,就像广岛的原子弹,我敲,威力必须是2222,起码是2222!

一致性:从一个状态转换到另一个状态,什么意思呢,例如从帐户A转一笔钱到帐户B上,如果帐户A上的钱减少了,而帐户B上的钱却没有增加,那么我们认为此时数据处于不一致的状态。

当然了,原子弹炸了,必须要造成伤害,或者是爆炸失败(回滚),没有可能说扔了原子弹,还爆炸了,没有造成伤害,这不是二踢脚吗bro!

隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

这个就抽象一点了,也不能并发扔原子弹啊,但是我来告诉你,原理都是一样的,A原子弹爆炸了,B原子弹就没有伤害了吗?

当然事务还有隔离级别

  • 读未提交:read uncommitted 读到别的事务没提交的数据,很严重的。
  • 读已提交:read committed A事务在进行中,B事务提交了,A事务读到了B事务的数据,不符合我们的隔离性啊
  • 可重复读:repeatable read A事务查询表有5条数据,进行了加锁,B事务添加一条数据,A事务又查询,哇多了一条这就是幻读,不加锁的数据没法控制啊bro!
  • 串行化:serializable Serializable 是最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执行,因此,脏读、不可重复读、幻读都不会出现。 都排队执行了,还有什么效率,这不公园买票吗?

持久性:一个事务一但提交了就是永久性的,数据会持久化到磁盘。

原子弹爆炸了💥就是伤害你,你只能一笑而过,回滚?,对不起他已经爆炸了!

那事务有这4个特性,是怎么实现的呢,整!

事务如何实现的?

利用回滚日志(undo log)重做日志(redo log) 两种表实现事务,并实现 MVCC (多版本并发控制) ; 下面举个例子,用updata的场景来说,因为insert不涉及到多版本。

  1. 将修改后的数据存入缓冲池(Buffer Pool)中,等待刷脏。
  2. 在Log Buffer中写入重做日志(Redo Log),并将日志状态设置为Prepare。
  3. 返回MySQL服务层,记录BinLog日志。
  4. 将Log Buffer中的日志文件状态设为Commit,并等待日志文件存入盘中。

下面我们来分析一下redo log 和undo log的作用:

redo log:叫做重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中。

简单的来说呢,就是一个事务,修改了数据,先要写redo日志,然后存储到缓存里,然后事务提交了,刷新到磁盘里。

undo log :undo log 叫做回滚日志,用于记录数据被修改前的信息。他正好跟前面所说的重做日志所记录的相反,重做日志记录数据被修改后的信息。undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。

这篇文章写的时间有点长了,好多内容都忘了,最近要重新找回状态,下一章我要写MVCC解决幻读问题、binlog、主从搭建,然后希望大家多多关注,我会超过宇哥🐢的!

相关推荐
码农派大星。3 分钟前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野10 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航13 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself29 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041533 分钟前
J2EE平台
java·java-ee
XiaoLeisj40 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
杜杜的man44 分钟前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*44 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu1 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s1 小时前
Golang--协程和管道
开发语言·后端·golang