MySQL高频面试题

2023-09-20 16:28:40

1.数据库存储引擎有:MyIsam、InnoDB、Memory、Archive、Federated

2.InnoDB采用的是B+树结构存储,B树的每个节点对应innoDB的一个page,一个page的大小一般为16K,非叶子节点只有键值,叶子节点包含完整数据

适用场景:

1)经常更新的表,适合处理多重并发的更新请求。

2)支持事务。

3)可以从灾难中恢复(通过 bin-log 日志等)。

4)外键约束。只有他支持外键。

5)支持自动增加列属性 auto_increment。

经典题目

1.B树和B+树的区别?

B树的特点:

  1. 一个节点里面有多个元素

  2. 排了序

    在这里插入图片描述

B+树的特点:

  1. 一个节点里面有多个元素
  2. 排了序
  3. 叶子节点之间有指针
  4. 非叶子节点上的元素都冗余了一份在叶子节点上(往B+树上面存的元素都会存在叶子节点上,且有序有指针连接)

在这里插入图片描述

2.Innodb中的B+树有什么特点?

在Mysql中,指针是双向的

在这里插入图片描述

3.什么是Innodb中的page?

B树的每个节点对应innoDB的一个page,一个page的大小一般为16KB,非叶子节点只有键值,叶子节点包含完整数据

(通过page去查询和插入,而不是一条一条查询,减少磁盘io)

在innodb中,在插入数据时,会按照索引字段升序排序插入,所以推荐主键索引字段id使用自增,以减少插入时耗费的性能。
在这里插入图片描述

页目录:存储每组数据的起始位置的元素序号值(索引值)以及指针指向每组的起始元素,减少查询时的遍历,是一种以空间换时间的思想。

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

在innodb中主键索引就是聚簇索引

在B+树中,从叶子节点开始从左往右找叫做全表扫描,从上往下找走索引

4.Innodb是如何支持范围查找走索引的?(比如查找为主键的a字段,a>6的记录)

a>6:先找a=6,再返回后面所有的数据

a<6:先找a=6,再返回前面所有的数据(双向指针,更好的支持范围查找)

5.为什么要遵循最左前缀原则才能利用到索引?

联合索引: 通过联合索引找到主键值后,再回主键索引中查找数据(回表)
在这里插入图片描述

最左前缀原则: 比如bcd联合索引,查询时必须要给出最左边的索引,即b必须要给。在从上往下扫描时,要满足最左前缀原则,如果是从叶子节点从左往右扫描(比如没有where条件),不需要满足。
在这里插入图片描述

索引下推(index condition Pushdown): 是MySQL5.6版本的新特性,它能减少回表查询次数,提高查询效率。(索引优化)

在这里插入图片描述

索引下推的目的是为了减少回表次数,也就是要减少IO操作。对于聚簇索引来说,数据和索引是在一起的,不存在回表这一说。

demo:https://baijiahao.baidu.com/s?id=1716515482593299829&wfr=spider&for=pc

6.范围查找导致索引失效原因

范围查找不一定会导致索引失效,引擎会根据搜索效率判断是走索引还是全表扫描,当走索引(数据多时,回表次数增加)效率低下时,索引失效,走全表扫描

7.覆盖索引的底层原理

覆盖索引: 只通过索引,就取到了所需要的数据,即需要查询的字段就是索引字段(或者主键字段),则使用索引,不需要回表

在这里插入图片描述

8.索引扫描底层原理

当没有加where条件时,查询联合索引中的索引字段值(不需要满足最左前缀原则),还是会走索引,不会走全表扫描。因为叶子节点通过索引存储相比于主键索引的叶子节点存储所有数据,所占的内存小,在查询时,可能只需遍历3个page,而全表扫描需要遍历4个page

9.order by为什么会导致索引失效?

select * from t1 order by b,c,d; bcd字段为联合索引

  • 走bcd索引 不需要排序+回表8次
  • 全表扫描 额外排序(内存,速度非常快) + 不用回表 √

select b from t1 order by b,c,d; 走索引

10.MySQL中的数据类型转换有哪些需要注意的?

在MySQL中,当查询条件的字段为数值类型时,对于不是数字的字符会转化成0,对于是数字的字符转化成数字

对字段进行了类型转换就用不了索引

11.对字段进行操作导致索引失效原理

对字段进行加减法操作或者类型转换后会导致索引失效,因为如果还走索引可能会破坏B+树的整体结构
在这里插入图片描述


12.MySQL的锁有哪些,如何理解?

按锁粒度分类:

  1. 行锁:锁某行数据,锁粒度最小,并发度高,会出现死锁。
  2. 表锁:锁整张表,锁粒度最大,并发度低,不会出现死锁。
  3. 间隙(页面)锁:锁的是一个区间,会出现死锁。

还可以分为:

  1. 共享锁:也就是读锁,一个事务给某行数据加了读锁,其它事务也可以读,可以加读锁,但是不能写,也不能加写锁。
  2. 排它锁:也就是写锁,一个事务给某行数据加了写锁,其他事务可以读,但是不能加读锁,不能加写锁,也不能写。

还可以分为:

  1. 乐观锁:乐观锁认为一个用户读数据的时候,别人不会去写自己所读的数据,并不会真正的去锁每行数据,而是通过一个版本号实现。
  2. 悲观锁:悲观锁就是在自己读或写数据的时候认为别人也刚好在写或者读数据,所以会对自己操作的数据加锁,只有等自己的整个事务提交了,才释放自己加上的锁。上面的行锁、表锁都是悲观锁。

13.Mysql慢查询该如何优化

  1. 检查是否走了索引,如果没有则优化SQL利用索引
  2. 检查所利用的索引是否是最优索引
  3. 检查所查字段是否都是必须的,去掉查出的多余数据
  4. 检查表中的数据是否过多了,是否应该进行分库分表
  5. 检查数据实例所在机器的性能配置是否太低,是否可以适当增加资源

14.聚簇索引和非聚簇索引的区别

都是B+树的数据结构

  • 聚簇索引:将数据存储和索引放到了一起,并且是按照一定的顺序组织的,找到了索引也就找打了数据,数据的物理存储顺序与索引数据是一致的。
  • 非聚簇索引:非聚簇索引中叶子节点不存储数据,存储的是数据行地址(辅助索引存放的是主键id),也就是说根据索引查找到数据行的位置,再去磁盘查找数据,也就是回表(非覆盖索引的情况下)。

在这里插入图片描述

15.如何实现分库分表?

在这里插入图片描述

水平分表通过保证id的唯一性拆分,分库可以使用hash方法,使用id对库的分区号取模,来保证负载均衡

垂直分表通过引入关联列类似于外键来拆分。

16.存储拆分后如何解决唯一主键?

因为要是分成多个表之后,每个表都是从 1 开始累加,这样是不对的,我们需要一个全局唯一的 id 来支持。

生成全局 id 有下面这几种方式:

  • UUID:不适合作为主键,因为太长了,并且无序不可读,查询效率低。比较适合用于生成唯一的名字的标示比如文件的名字。

  • 数据库自增 id : 两台数据库分别设置不同步长,生成不重复ID的策略来实现高可用。这种方式生成的 id 有序,但是需要独立部署数据库实例,成本高,还会有性能瓶颈。

  • 利用 redis 生成 id : 性能比较好,灵活方便,不依赖于数据库。但是,引入了新的组件造成系统更加复杂,可用性降低,编码更加复杂,增加了系统成本。

  • Twitter的snowflake算法 : SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序。

在这里插入图片描述

  • 美团的Leaf分布式ID生成系统 :Leaf 是美团开源的分布式ID生成器,能保证全局唯一性、趋势递增、单调递增、信息安全,里面也提到了几种分布式方案的对比,但也需要依赖关系数据库、Zookeeper等中间件。感觉还不错。

17.ACID靠什么保证的

​ 1、原子性是由undolog日志来保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql。

​ 2、一致性是由其他三大特征保证,程序代码要保证业务上的一致性。

​ 3、隔离性是由MVCC来保证

​ 4、持久性由redolog来保证,MySQL修改数据的时候会在redolog中记录一份日志数据,就算数据没有保存成 功,只要日志保存成功了,数据仍然不会丢失。

18.什么是MVCC

MVCC 全称是 Multi-Version Concurrency Control,即多版本并发控制,在读取数据时通过一种类似快照的方式将数据保存下来,它可以让读写操作不互斥,提高数据库的并发性能和一致性。

InnoDB行记录中出了记录业务数据外,还有两个隐藏的字段,分别是trx_id和roll_pointer。

trx_id表示最近修改该行记录的事务id,roll_ptr相当于一个指针,指向上一个版本的地址。

InnoDB中使用undo log来实现多版本和事务回滚的功能,undo log分为insert undo log和update undo log。

  • insert undo log记录了插入操作产生的新行记录,在事务提交后可以删除。
  • update undo log记录了个更新或删除操作之前的旧记录,在事务提交后不能立即删除,因为其它事务可能需要这个undo log来获取某个版本的数据。

InnoDB使用ReadView来判断一个数据版本是否对当前事务可见的一个数据结构,Mysql支持四种隔离级别:(READ COMMITTED)读已提交,(READ UNCOMMITTED)读未提交,(REPEATABLE READ)可重复读,(SERIALIZABLE)串行化。其中MVCC只在读已提交和可重复读两种级别下工作,因为 READ UNCOMMITTED 总是读取最新的数据行,而不是符合当前事务版本的数据行;而 SERIALIZABLE 则会对所有读取的行都加锁。

- 对于 READ COMMITTED 隔离级别,每次执行查询语句时都会生成一个新的 ReadView,这样可以保证每次查询都能看到最新提交的数据。

- 对于 REPEATABLE READ 隔离级别,第一次执行查询语句时会生成一个 ReadView,并在整个事务中复用这个 ReadView,这样可以保证在同一个事务中多次查询结果一致。

https://baijiahao.baidu.com/s?id=1764154588499784629&wfr=spider&for=pc

19.Mysql主从同步原理

Mysql主从复制中主要有三个线程,Master一条线程和Slave中的两条线程,master(binlog dump thread)、slave(I/O thread 、 SQL thread)。

  • 主库将数据的操作记录到一个二进制日志中,即binlog。
  • 当binlog日志有变动时,log dump线程读取其内容并发送给从库。
  • 从库的I/O线程接受binlog内容,并将其写入到relay log中继日志中。
  • 从库的SQL线程读取relay log文件内容对从库数据更新进行重放,最终保证数据的一致性。

在这里插入图片描述

主从复制的三种方式:

  1. 异步复制: 主库只需要完成自己的数据库操作即可,至于从库是否收到二进制日志,是否完成操作,主库不用关心。这是Mysql默认的复制方式,但是会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库就升为主库,日志就丢失了。
  2. 同步复制: 主库等所有从库执行完成后才返回给客户端,这个方式显然性能会受到很大影响。
  3. 半同步复制: 主库只保证至少一个从库操作成功后就返回。

20.事务的基本特征和隔离级别

事务基本特性ACID分别是:

​ 1、原子性指的是一个事务中的操作要么全部成功要么全部失败。

​ 2、一致性是由其他三大特征保证,指的是数据库总是从一个一致性的状态转换到另一个一致性的状态,程序代码要保证业务上的一致性,比如转账案例余额不足。

​ 3、隔离性指的是一个事务在最终提交前,对其他事务不可见,隔离性是由MVCC来保证。

​ 4、持久性由redolog来保证,MySQL修改数据的时候会在redolog中记录一份日志数据,就算数据没有保存成 功,只要日志保存成功了,数据仍然不会丢失(一旦提交事务,所做的修改就会永久保存到数据库中)。

隔离性有4个隔离级别:

  1. read uncommit 读未提交: 可能会读到其它事务未提交的数据,如果其它更新事务因为某种原因操作失败回滚了,就会出现脏读。
  2. read commit 读已提交: 两次读取结果不一致,也叫不可重复读。
  3. repeatable read 可重复读: 这是mysql的默认级别,可能会产生幻读,幻读是指在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几行数据,而另一个事务在此时插入了几行数据,先前的事务在查询中,就会发现有几行数据是之前没有的。
  4. serializable 串行化: 一般不会使用,会给每一行读取的数据都加锁,会导致大量超时和锁竞争问题。
更多推荐

Nuxt 菜鸟入门学习笔记:路由

文章目录路由Routing页面Pages导航Navigation路由参数RouteParameters路由中间件RouteMiddleware路由验证RouteValidationNuxt官网地址:https://nuxt.com/路由RoutingNuxt的一个核心功能是文件系统路由器。pages/目录下的每个Vue

大数据运维一些常见批量操作命令

大数据运维中,批量操作是一项常见的任务。在使用flume进行数据采集的过程中,有时会出现故障导致采集停止,此时积累了大量的文件。如果想要将这些文件迁移到新的目录,直接使用"mv"命令可能会因为文件数目过多而报错。为了解决这个问题,我们可以利用管道技术和"xargs"命令。"xargs"是一个用于给命令传递参数的过滤器,

【React】面试题5题

1.说说你对dangerouslySetInnerHTML的理解dangerouslySetInnerHTML是React中的一个属性,用于将HTML代码作为字符串直接插入到组件中的DOM元素中。它可以用来动态地生成HTML内容,但同时也带来了一些潜在的安全风险。使用dangerouslySetInnerHTML时,需

Gartner 公布 2023新兴技术成熟度曲线,AI依然是全村的希望,从云端到边缘延伸...

边缘计算社区从Gartner官网了解到,近日,Gartner公布了2023年新兴技术成熟度曲线以及最新的技术趋势。2023新兴技术成熟度曲线2023年Gartner技术成熟度曲线确定了25项值得关注的新兴技术,它们将为企业架构和技术创新领导者提供助力。这些技术有望在未来2-10年内对商业及社会产生显著影响。使CIO和I

Windows环境变量 和 Linux环境变量

环境变量就像是一张地图,告诉程序员和程序在哪里可以找到所需的资源和工具。🗺🗺一、Windows环境变量1.1什么是Windows环境变量?1.2Windows环境变量的设置和访问1.21设置环境变量1.22查看环境变量1.3常见的Windows环境变量1.4环境变量的作用1.5Windows环境变量长度限制问题二、

【C# 基础精讲】List 集合的使用

在C#中,List<T>是一种非常常用的泛型集合类,用于存储一组相同类型的元素。List<T>具有动态调整大小的能力,可以方便地添加、删除、查找和修改元素,非常灵活和高效。本文将详细介绍List<T>集合的使用方法,包括创建List<T>对象、添加元素、删除元素、查找元素、遍历集合以及常用的List<T>方法等内容。1

RockyLinux9.2 网卡配置和nmcli、nmtui命令的使用

NetworkManagerNetworkManager是一个标准的Linux网络配置工具套件,支持服务器,也支持桌面环境,发展到如今,绝大多数流行的发行版都支持它。这套网络配置工具适用于RockyLinux8及更高版本。nmcli是nm的命令行工具、nmtui是nm的ui工具nmcli查看网络信息ipa或者nmcli

Linux文件内容查看和编辑指南:cat、less、grep等常用命令详解

文章目录Linux文件内容查看和编辑1.查看文件内容cat用法cat详解概要主要用途参数选项返回值例子注意lessless详解补充说明语法选项参数实例moremore详解补充说明语法选项参数实例2.文件搜索和过滤grepgrep详解语法选项参数实例findfind详解语法选项参数实例awkawk详解语法选项参数实例3.

深入浅出之数组

深入浅出之数组文章目录:深入浅出之数组一、数组的基本语法1.1数组声明1.2数组初始化二、多维数组2.1多维数组的基本语法2.2多维数组的适用场景三、数组的实际练习(传智杯真题为例)一、数组的基本语法1.1数组声明数组声明通常为valuename[number]的形式。value是值得数据类型,name是数组名称,nu

物联网如何助力乡村数字经济发展

在当今移动互联网时代,信息化数字化已经渗透了我们生活的方方面面,数字物联网转型也成为各个产业的重要动力。对于广大乡村来说,得益于网络基础设施的全面建成覆盖,乡村各产业也迎来数字化新业态转型,创新诞生了基于物联网的数字农业、数字养殖、数字文旅、数字农村电商等一系列新模式,本篇就为大家简答介绍一下物联网如何打造乡村数字经济

Ingress Controller

什么是IngressController?在云原生生态中,通常来讲,入口控制器(IngressController)是Kubernetes中的一个关键组件,用于管理入口资源对象。Ingress资源对象用于定义来自外网的HTTP和HTTPS规则,以控制进入集群内服务的流量。而IngressController则是真正实现

热文推荐