Mysql面试必知的知识点-干货分享

news/2024/11/19 23:18:18/

文章目录

      • 底层索引为什么使用B+树,而不用B树?
      • 为什么Innodb索引建议必须建主键?
      • 为什么主键推荐使用整形自增?
      • Mysql底层索引只有B+树吗?
      • 联合索引底层长什么样子?
      • 数据库隔离级别中串行化是怎么实现的?
      • 查询方法需要加事务吗?
      • 大事务有什么影响?

底层索引为什么使用B+树,而不用B树?

在这里插入图片描述
在这里插入图片描述

在Mysql内部,对于Innodb存储引擎, 每一个节点都会占一个磁盘页,一个磁盘页的大小默认是16kb.

在这里插入图片描述

也就是说每一个节点存储的东西最多只能有16kb

在这里插入图片描述

那么在b树中,这16kb及需要存储索引,又需要存储真实数据. 而在b+树中,这16kb只需要存储索引, 所以在b+树中一个节点可以存储更多的索引,从整体看, 就会比b树更加的矮胖, 从而可以减少树的深度,减少I/O次数.

为什么Innodb索引建议必须建主键?

首先明确在Innodb索引中, 是依靠B+树来组织整张表数据的, 而默认的话会用主键索引来组织.

那你现在没有主键怎么办?没有索引来组织这个B+树,怎么办呢?

其实Mysql首先会在你的数据表中找,从左往右找,找到一列可以做唯一性索引的, 把该列作为主键,用来维护整张表的数据.建一个B+树.

那如果找不到这列数据呢?Mysql其实还有一个隐藏列->rowid, 这一列对默认递增, 以此作为主键, 用来维护B+树.但其实这种方式并不好,因为我们并看不到这列, 在查询的时候也不能用该列去查询数据.

为什么主键推荐使用整形自增?

这个是两个问题.

1.为什么使用整形?
因为在使用索引查找元素的时候,会进行大量的比较,来确定位置,那如果是整形的话,会效率更高.

2.为什么要自增?
在B+树中,叶子节点是从左到右依次递增的

如果是自增,就只会在叶子节点的最右边新加一个节点即可, 而如果不是自增,就需要根据主键的索引值进行随机插入,那可能就会插入到某个叶子节点的中间位置,此时就需要移动其他数据,甚至需要从一个页面复制到另一个页面,我们将这种情况称为页分裂.页分裂会造成大量的内存碎片,导致结构不紧凑,从而影响查询效率

所以用自增的话,相比来说,效率会更高.

Mysql底层索引只有B+树吗?

其实不是,在Mysql底层,默认是B+树这种索引结构,但其实还有 Hash表,我们也可以选择这种数据结构,但大多数情况下不会使用,为什么?

在这里插入图片描述
Hash结构有它的优点:

  1. 很多时候是比B+索引要快的,更加高效
  2. 只需要一次Hash计算就能定位出数据存储的位置

但是为什么不用呢?

最主要的点就是不支持范围查询, 而在我们业务中,范围查询是一个非常常见的需要, 而B+树就可以很好的范围查询.

联合索引底层长什么样子?

联合索引是一个非聚集索引.如下:
使用name、age、position三个字段建立联合索引
在这里插入图片描述
在排序的时候,先按第一个字段name排,第一个字段相同的时候才按第二个字段age排序,第二个字段相同的时候按照第三个字段position排序. 这也是为什么会有最左前缀匹配原则

数据库隔离级别中串行化是怎么实现的?

这个其实很简单,所谓串行化, 就是把所有的涉及到相同数据的读写, 写写的这些操作全部串行.读读是不影响的.

比如说A事务先读取一条数据, select * from user where id=1;但是A事务还没有提交
此时B事务去更新update user set name=‘a’ where id=1;会是什么效果?

此时B事务就会被阻塞住,直到A事务提交之后.
要实现这种效果其实非常简单,就是对所有的读操作都加上读锁, 也就是都变成当前读, select … lock in share mode;

查询方法需要加事务吗?

在我们的Java项目某个方法中,只有查询操作,这个查询可能有多个, 这个方法需要加事务吗?

要理清楚这个问题,首先要明白 加事务查询和不加事务查询的区别:

快照读:

  • 不加事务: 读取的都是所有事务已经提交的数据.
  • 加事务: 和事务对应的隔离级别有关系,
    1. 读未提交: 可能读到其他事务未提交的数据
    2. 读已提交: 读取到的是所有事务已经提交的数据.
    3. 可重复读: 可能读取到的可能是历史数据,因为在当前隔离级别中, 所有读取的数据都来自开启事务后第一次读取的快照数据.
    4. 串行化: 读写操作,写写操作会被阻塞.

当前读:

  • 因为当前读是相当于加读锁的,所以对于当前读, 不加事务和加事务在所有情况下效果都是一样的.

我们平常大部分查询都是快照读, 事务的隔离级别大部分都是读已提交或者可重复读.接下来我们再重点说下这两种情况:

快照读-读已提交:
这种情况下其实不需要加事务读了,因为加事务读和不加事务读取到的结果都是一样的, 都会读取到其他事务已经提交的最新数据.

快照读-可重复读:
这种情况下就有区别了, 具体需要根据业务场景判断加不加,举个例子:

  • 比如说需要生成报表, 那报表其实就需要的是某个时间点的数据, 也就是某个版本的快照数据, 因为要保证数据整体上的一致性.所以就需要加事务去读.
  • 比如说某个场景就需要最新的数据, 那就最好不加事务,这样读取的就是所有事务已经提交的最新数据.

大事务有什么影响?

  1. 并发情况下, 数据库连接池容易被撑爆
  2. 大事务一般当前读会比较多, 容易造成大量阻塞和锁超时
  3. 执行时间长, 容易造成主从延迟
  4. 回滚需要的时间比较长
  5. undo log日志膨胀

今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述


http://www.ppmy.cn/news/98523.html

相关文章

解决websocket在部署到服务器https下无法使用的问题

目录 一、问题 1.1 问题描述 1.2 问题详细描述 二、解决 2.1 https下的链接类型 2.2 修改Nginx的配置 一、问题 1.1 问题描述 一个小项目中使用到了websocket,这个websocket在本地完全是完全正常运行的,不管是前后台的信息通讯 还是 异常报错接收…

XDP入门--eBPF程序实现网桥/二层交换机转发功能

本文目录 1、试验环境2、eBPF字节码源代码实现3、用户态应用层管理与控制程序的源代码实现4、编译与运行5、测试结果 我们在此文的进阶部分 或者 此文中已经描述了如何设置Linux网桥,并将多个以太接口加入网桥后实现一个最基本的二层交换机的二层交换转发功能。Linu…

Linux下的yum和vim

目录 一、Linux软件包管理器yum1.1 何为软件包?1.2 rzsz工具1.3 如何安装和卸载软件?1.4 Linux的软件生态 二、vim文本编辑器 一、Linux软件包管理器yum 1.1 何为软件包? 软件包可以理解成是windows下别人提前编译好的安装包程序&#xff0…

Linux——使用命令行参数管理环境变量

目录 使用命令行参数获取用户在DOS命令行输入的指令: 方法:代码如下: 使用命令行参数获取并打印部分或者整体环境变量的方法: 方法1: 运行结果: 方法2:使用外部链接environ: 使用命令行参数…

应该选择网络安全还是程序员?

很长的时间我都在思考这个问题.,根据自己的经验和朋友们的讨论后得出了一些结论,网络安全 这个概念太广,我就以安服/渗透岗作为比较的对象,题主可以参考一下: 程序员: 优点: 1.薪资非常高&a…

【js】对象属性的拦截和Proxy代理与Reflect映射的用法与区别

✍️ 作者简介: 前端新手学习中。 💂 作者主页: 作者主页查看更多前端教学 🎓 专栏分享:css重难点教学 Node.js教学 从头开始学习 ajax学习 文章目录 对象属性的拦截介绍SetGet 对象的拦截介绍使用对象属性拦截和对象拦截区别练习题 映射…

Etcdctl 命令v3

一、v3必须导出环境变量 export ETCDCTL_API3 二、查看版本 etcdctl version 三、写入键 1.基本 etcdctl put foo bar 2.绑定租约 etcdctl put foo bar --leasexxxx 四、获取键 1.基本 etcdctl get foo 2.按十六进制获取 etcdctl get foo --hex 3.只读取键值 et…

Spring高手之路——深入理解与实现IOC依赖查找与依赖注入

本文从xml开始讲解,注解后面给出 文章目录 1. 一个最基本的 IOC 依赖查找实例2. IOC 的两种实现方式2.1 依赖查找(Dependency Lookup)2.2 依赖注入(Dependency Injection) 3. 在三层架构中的 service 层与 dao 层体会依…