首页 > 数据库 >【MySQL】mysql索引和事务(面试经典问题)

【MySQL】mysql索引和事务(面试经典问题)

时间:2024-08-28 12:22:48浏览次数:14  
标签:事务 mysql 查询 索引 MySQL 执行 数据 节点

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



目录

mysql索引

代价

查看索引

创建索引

 删除索引

索引背后的数据结构

B树

B+树

B+树与B树的区别

B+树的优势

mysql事务

 事务 涉及的四个核心特性:

隔离性详细解释

脏读

不可重复读

幻读

隔离性的四个级别

read uncommitted 读未提交

read committed  读已提交

repeatable read 可重复读

serializable 串行化


mysql索引

索引 类似于书的 目录,引入 索引 是为了 提高查询的速度

select这样的操作,默认是按照"遍历"的方式来查询,即时间复杂度为O(n),但这里的 读的是硬盘,而在数据结构里的O(n) ,遍历的是内存

代价

  • 引入索引 需要消耗额外的 存储空间
  • 引入索引后,确实能提高 查询的效率 ,但可能会影响 增删改的 效率(有时会 更快,有时会更慢,也或者 没变化)

比如: 通过条件判断 的方式来 删除 delete from student where id = 5; 其中where id=5 背后就有查询操作

索引有利有弊,实际开发中 还是推荐使用 索引

  • 硬盘往往不是主要矛盾
  • 对于增删改查 也不一定都是 负面影响,也可能会 触发一些正面效果
  • 很多业务场景 查询的 频率 要比 增删改 要高很多

查看索引

show index from 表名;

主键自带索引

unique 和 foreign key 也自带索引

创建索引

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

创建索引 其实是一个危险操作,针对 空表 或者 表中只有 较少数据(几千,几万...)创建索引 谈不上危险 但是一旦数据量 比较大( 千万级别),此时创建索引操作 可能会触发 大量的硬盘IO,直接把机器卡死了,  所以在 最初建表时 要哪些索引要提前规划好,创建好

 删除索引

drop index 索引名 on 表名;

只能删除 自己创建的索引,不能删除自动生成的  ,删索引也是 危险操作.

索引背后的数据结构

 所谓"构建索引" 其实是 引入一些数据结构 对数据进行存储,从而 提高查找速度~

二叉搜索树 和 哈希表 的查找效率都很高,但是都不适合 给数据库做索引

原因:

  • 二叉搜索树 最大的问题在于 "二叉",当要保存的 元素多的时候,会使整个树的 高度变高(高度变高,比较的次数就会变多,伤硬盘~)
  • 哈希表 最大的问题在于 只能进行"相等" 查询,无法进行 < >这样的'范围查询',也无法进行 like 模糊查询(哈希表 是通过哈希函数 把查询的key 映射成 数组下标)

B树

也写做 B-树(这里的 - 是连接符)

B树 是N叉搜索树(每个节点 ,可以有 多个子树,树的度是 N, 这样降低了树的高度)

每个节点不是 存储一个key值,而是会存多个  ,某个节点保存了 N个key,就能延伸出 N+1个子树,

和某个节点比较的时候,先一次硬盘IO,把所有的这个节点的内容都读出来,再在内存中比较,这里最主要的目的: 不是为了减少 比较的次数 而是要减少 硬盘IO的次数

B+树

B+树 ,为数据库 量身定做的数据结构  ,针对B树做的进一步改进的数据结构,B+树也是N叉搜索树

上图中的15是该B+树的最大值

若要进行 范围查询id>4 and id<10 ,从4开始,沿着链表往后遍历到10即可完成查询~

B+树与B树的区别

  • B树 是有N个key,划分成N+1个区间  ,B+树 是有N 个key,划分出N个区间
  • 父节点中的key值 会在下面的子节点中再次出现 (成为子节点最大值)
  • B+树把叶子节点 像一个链表一样 连在一起了(此时进行 '范围查询' 就非常方便了)

B+树的优势

  • N叉搜索树,树的高度比较低,此时硬盘IO次数就比较少
  • 叶子节点是全集, 并且用链表结构连接,非常便于范围查询
  • B+树 所有查询都要落在叶子节点上完成的  ,任何一次查询,经历的IO次数和比较次数 都是差不多的,查询的开销稳定(稳定意味着 成本容易被预估出来)
  • B+树的叶子节点是全集,所以 非叶子节点上不必存储 "数据行"(比如:数据行: "1 ,张三,  男,  100分),只需要存储索引列的 key即可(非叶子节点占据的空间小,可以直接加载到内存中,进一步减少了硬盘IO的访问次数)

mysql事务

事务 是用来解决一类 特殊场景的问题(有些场景,完成某个操作,需要多个sql 配合完成,例如 转账)

事务 是把多个执行的SQL 打包成一个'整体',这个整体 在执行的过程中要做到 要么整个执行完,要么一个都不执行  (这里的"一个都不执行"实际上是"回滚"机制),避免出现 类似于" 转账转一半" 的情况.

回滚 :当sql执行到一半发现出错了 ,数据库会自动进行"还原操作"(相当于把前面执行过的sql给 '撤销'了,最终效果就像 一个sql都没有执行的效果). 回滚操作 只是针对 事务 来说,不能将想 "drop database "这样的操作 回滚回来

 事务 涉及的四个核心特性:

  • 原子性(最重要的特性),上面提到的 '整体'即原子性.
  • 一致性 ,事务执行的前后数据库中的数据都是'合法状态',不会出现 非法的临时结果的状态
  • 持久性.事务执行完毕后,就会修改 硬盘上的数据,事务都是会持久生效的.
  • 隔离性, 描述了 多个事务 并发执行的时候 相互之间产生的影响是怎样的

隔离性详细解释

并发执行:  mysql是一个 '客户端- 服务器'结构的程序,  一个服务器通常会给多个客户端 同时提供服务,因此  很可能,多个客户端会同时向 这个服务器提交事务来执行,服务器就要同时执行这些多个事务,此时就是 并发执行.

若此时 同时执行的事务 恰好是针对同一个表 进行 增删改查 ,此时就可能会引入 一些问题:
脏读 ,不可重复读 , 幻读.

脏读

指一个事务读取的数据是 "脏数据"(过时的数据)

举例: 有两个事务A和B 并发执行,

其中 事务A 是针对某个表的数据 进行修改 .A执行过程中,B也去读取这个表的数据, 当B读完后,A把表中的数据又改成了别的,

这样就会导致B读到的数据 不是最终的"正确数据" ,而是临时性的 "脏数据"

解决方法: 给写操作加锁(即在修改的时候,不能读) 

不可重复读

 指的是 一个事务里 多次读取的结果不一样

举例: 有三个事务ABC ,

事务A执行完一个修改操作,提交数据,事务B再执行,读取刚才A提交的数据,

在B读取的过程中,事务C又对刚才A修改的数据 再次做出了修改

对B来说,后续读到的这个数据 和第一次读到的是不一样的.

 解决方法: 给读操作加锁(一个事务在读取数据的过程中,其他事务不能修改它正在读的数据)

幻读

幻读 是不可重复读的特殊情况

举例"事务A在读取数据时 ,事务B 新增 或 删除了一些数据

A多次读取的数据虽然 一样,但是 '结果集'不同

解决方法:'串行化'(只要是 读的时候,就不要有任何操作.)

隔离性的四个级别

针对上面3个问题, mysql 提供了四个隔离级别,可以通过 配置文件来设置当前服务器的隔离级别

设置不同的隔离级别 会使事务间的并发执行产生的影响有差别

read uncommitted 读未提交

一个事务可以读取 另一个事务未提交的数据,此时就可能会产生 脏读.不可重复读,幻读 三个问题

但是此时,多个事务并发执行的程度是 最高的,执行速度也最快.

read committed  读已提交

一个事务只能读取另一个事务提交之后的数据(给写操作加锁),此时会产生 不可重复读 和 幻读 两个问题(脏读问题解决了),此时并发程度会降低,执行速度会变慢,但是事务之间的隔离性提高了(事物之间影响变小了,得到的数据更准确了)

repeatable read 可重复读

相当于给读操作和写操作都加锁了.此时可能会产生 幻读问题(解决了脏读和不可重复读问题),

并发程度进一步降低,执行速度进一步变慢, 事务的隔离性进一步提高了.

serializable 串行化

所有事务都是在服务器上一个接一个的执行的,此时解决了脏读,不可重复读,幻读问题

并发程度最低,执行速度最慢,隔离性最高,数据最准确

标签:事务,mysql,查询,索引,MySQL,执行,数据,节点
From: https://blog.csdn.net/2301_80898480/article/details/141568087

相关文章

  • 折腾 Quickwit,Rust 编写的分布式搜索引擎 - 从不同的来源摄取数据
    摄取API在这节教程中,我们将介绍如何使用IngestAPI向Quickwit发送数据。要跟随这节教程,您需要有一个本地的Quickwit实例正在运行。https://quickwit.io/docs/get-started/installation要启动它,请在终端中运行./quickwitrun。创建索引首先,我们创建一个无模式的索......
  • MySQL索引底层实现原理
    索引的本质MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。我们知道,数据库查询是数据库的最主要功能之一。我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化。最......
  • 查看mysql的版本号
    1.1在命令行登录mysql,即可看到mysql的版本号[root@heyong~]#mysql-uroot-pEnterpassword:WelcometotheMySQLmonitor.Commandsendwith;or\g.YourMySQLconnectionidis487032Serverversion:5.7.17MySQLCommunityServer(GPL)Copyright(c)2000,......
  • Express+MySQL+Sequelize实作API
    本文章为观看哔站视频Express+MySQL+Sequelize实作API所作随笔,边敲代码便跟学......
  • 【Rust光年纪】解锁Rust开发新姿势:数据库客户端和搜索引擎库探秘
    用Rust打造高效应用:数据库客户端与搜索引擎库全攻略前言随着Rust语言的不断发展,越来越多的优秀库和工具涌现出来,为开发者提供了更多选择和便利。本文将介绍几个用于Rust语言的数据库客户端和搜索引擎库,它们在不同领域都展现出了强大的功能和灵活的应用场景。欢迎订阅专......
  • mysql 开启和关闭日志记录
    开启和关闭日志记录(临时)#默认情况下mysql是不会记录最近执行sql语句的,需要手动开启才能记录。另外sql语句有两种方式记录,记录到table,记录到文件。另外开启日志记录多少会占用性能,适合开发测试环境使用。--临时设置,重启MySQL服务失效showvariableslike'general_log%';--......
  • springboot+vue+mybatis计算机毕业设计电影影评的垂直搜索引擎+PPT+论文+讲解+售后
    近年来,科技飞速发展,在经济全球化的背景之下,大数据将进一步提高社会综合发展的效率和速度,大数据技术也会涉及到各个领域,而爬虫实现网站数据可视化在网站数据可视化背景下有着无法忽视的作用。管理信息系统的开发是一个不断优化的过程,随着网络大数据时代的到来,管理信息系统与大......
  • MySQL数据库(2)——DML、视图、函数
    目录1、DML——数据操作语言(DataManipulationLanguage)2、添加数据2.1语句添加2.2文件加载3、修改数据4、删除数据5、查询数据5.1DQL基本关键字及其说明 着重号SQL简单查询5.2别名查询5.3去重查询5.4单表查询算数运算符比较运算符逻辑运算符范围......
  • MySQL之mysqldump的使用详解
    一、mysqldump简介mysqldump 是 MySQL 自带的逻辑备份工具。它的备份原理是通过协议连接到 MySQL 数据库,将需要备份的数据查询出来,将查询出的数据转换成对应的insert 语句,当我们需要还原这些数据时,只要执行这些 insert 语句,即可将对应的数据还原。二、备份命令2.1命......
  • Mysql 通过binlog日志恢复数据
    Binlog日志,即binarylog,是二进制日志文件,有两个作用,一个是增量备份,另一个是主从复制,即主节点维护一个binlog日志文件,从节点从binlog中同步数据,也可以通过binlog日志来恢复数据1,登录mysql查看binlog日志的状态,输入showvariableslike‘%log_bin%’;查看binlog为off关闭状态2,开......