数据库方面-----面试真题汇总(含答案)

全部是各大厂的数据方面的真是面试题

面试题1. MySQL如何在RR隔离级别下避免幻读问题:Next-Key锁(代表行锁和GAP间隙锁的合并)?

  • 其实是通过间隙锁和行锁共同来解决的幻读问题,在RR隔离级别下,行锁的原理,如果有一个事务A在进行update一个主键ID为2的数据,那么此时如果事务B过来进行插入ID为2的数据的话那么此时的行锁就保证了事务B必须阻塞等待事务Acommit之后,事务B的操作才会生效
  • 而下面的间隙锁就是数据库中只有teacher_id为5和30,中间这部分就是间隙锁要加锁的范围。update的teacher_id=20是在(5,30]区间,即使没有修改任何数据,Innodb也会在这个区间加gap锁,而其它区间不会影响,事务C正常插入。

如果使用的是没有索引的字段,比如update class_teacher set teacher_id=7 where class_name=‘初三八班(即使没有匹配到任何数据)’,那么会给全表加入gap锁。同时,它不能像上文中行锁一样经过MySQL Server过滤自动解除不满足条件的锁,因为没有索引,则这些字段也就没有排序,也就没有区间。除非该事务提交,否则其它事务无法插入任何数据

总结:行锁防止别的事务修改或删除,GAP锁防止别的事务新增,行锁和GAP锁结合形成的的Next-Key锁共同解决了RR级别在写数据时的幻读问题
在这里插入图片描述

面试题2. MySQL的引擎讲一下,有什么区别,使用场景呢?

首先MySQL的引擎分为innodb和myisam 两种,而且默认使用的是innodb的引擎。

两者的区别:
2. 事务方面:innodb是事务安全的,而myisam非事务安全的
3. 锁机制方面:innodb是行级锁的,而myisam是表级锁的
4. 存储方面:innodb是聚集索引,也就是说他的索引和数据都是在一起的,而myisam是非聚集索引,也就是说他的索引和数据文件是分开的。
5. 事务外键:mysiam表不支持外键,而InnoDB支持
6. 查询方面:当进行select count(*)from table 的时候,mysiam是直接读取除本身就保存有的变量,而innodb则需要进行全表扫描,效率相对比较低,但是如果在使用innodb的时候加上where条件查询的话就会和myisam的操作一样
两者的使用场景:
7. MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。
8. InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且行锁定的机会比较大的情况

自己的一些总结:

  • 首先Myisam使用的是非聚集索引(也就是物理数据和索引是分开存储的,索引只存储在非叶子节点,只有真是的数据库的行数据的物理地址才存储在最下层的叶子节点上),所以底层使用的是B+tree来进行实现的底层
  • 而Innodb使用的是聚集索引(也就是物理数据和索引是存储在同一个叶子节点上的),但是底层使用的也是B+tree来进行实现的底层的存储。

面试题3. mysql的索引讲一下,一级和二级索引的区别,什么时候可以不用查一级索引

  • 首先一级索引其实就是当你的MySQL中有主键的时候,该主键就是一级索引,二级索引就是可以根据我们自己需要的字段可以去建立二级索引。

为什么索引能提高查询效率?

先看一下索引的结构:
在这里插入图片描述
上面其实就是一个叶子
在这里插入图片描述
其实MySQL中B+的每一个节点就是对应一页,站在的数据结构的角度来看,其实节点就是页为单位,但是每一个页中的数据又含有了很多条数据记录,这个记录对应的就是数据库中按照主键进行排列的顺序
在这里插入图片描述

面试题4. MySQL的事务性质怎么实现的,其中的持久性和隔离性说一下。默认级别是哪个,通过什么实现的

MySQL的事务性质怎么实现的?

  • 首先MySQL的事务是有四个特性A(原子性)、C(一致性)、I(隔离性)D(持久性),而原子性、一致性、持久性是由数据库中的redo log 和undo log来完成的,而隔离性是通过数据的加锁来进行实现的
  • redo log用来保证事务的持久性,其实就是将该事务的所有日志写入到重做日志文件进行持久化,待事务的commit操作完成才算完成。
  • undo log其实就是为了事务的回滚而生的,因为在提交事务的时候,有可能会失败,这时就需要undo log来进行回滚事件。

MySQL的默认隔离级别是RR级别(repeat read重复读)

面试题5. MySQL索引的实现,innodb的索引,b+树索引是怎么实现的,为什么用b+树做索引节点,一个节点存了多少数据,怎么规定大小,与磁盘页对应。

面试题5. MySQL的事务隔离级别,分别解决什么问题。

(1)read uncommitted(读取未提交数据)
出现的情景就是,当有一个事务A对数据库进行插入了一条数据(插入之后的数据为11条,插入之前为10条),此时另外有一个事务B先查询了数据有11条(因为到这的时候A事务并没有提交),之后事务A才提交事务,这时事务B又去查询数据库发现变成了10条。此时的问题:事务B心想,我刚刚查的数据是11条啊,为啥这次又查询的数据又变成10条了?,肯定是我读错了。。。

  • 结论:我们将事务隔离级别设置为read uncommitted,即便是事务没有commit,但是我们仍然能读到未提交的数据,这是所有隔离级别中最低的一种
  • 出现的问题:只要一个事务A开启之后,无论有没有提交,不管做的修改和添加的任何操作,在其他的事务中都能读取到事务A的操作,这就是最低级的一个隔离级别,所以会出现脏读。

(2)read committed(可以读取其他事务提交的数据)—大多数数据库默认的隔离级别。这个级别其实是进一步改善第一种的隔离级别,
情景为;当一个事务A开始之后,执行把小明的钱增加20(没有增加前是100),此时事务A查询到的小明的钱已经变成了120(到这的时候事务A还没有提交事务),此时事务B过来去查询小明的钱还是100,但是这个时候事务A才去提交事务,但是事务B再去查询发现小明的钱发现变成了120,这个事务B就纳闷了,刚刚我查询的还是100的,为啥突然就变成120了,两次查询的结果不一致,出现的问题就是不可重复读。。

  • 结论:当我们将当前会话的隔离级别设置为read committed的时候,当前会话只能读取到其他事务提交过的数据,未提交的数据读不到。
  • 出现的问题:当我们在一个回话B事务中,读取到两次不同的结果,这就造成了不可重复读,这就造成了不可重复读的问题,继续解决。

(3)repeatable read(可重读)—MySQL默认的隔离级别
情景就是:现在我在事务A中开启可重复读的级别事务,并添加了一条数据(本来是10条数据),事务A先查询数据为11条(这里事务A先检验一下添加成工了),然后在事务B中查询到的数据却为10条(此时B不知道A已经插入数据且成功了),但是此时事务B想插入同一条数据(也就是第11条数据),但是却报错了,说已经不能重复插入数据,然后事务B开始想,我明明看到的是只有10条数据啊,为啥不让我插第11条,他心想难到是我看错了。(所以这就是幻读的问题。,。)

  • 结论:当我们将当前会话的隔离级别设置为repeatable read的时候,当前会话可以重复读,就是每次读取的结果集都相同,而不管其他事务有没有提交。
  • 出现的问题:事务A添加了一条数据,并且成功此时事务A验证的时候为11条,还没有提交,事务B过来查询发现数据还是10条,然后事务B去插入同样的第11条数据,并没有成功(提示说不能重复插入第11条数据,怀疑自己是不是看错了,幻读问题。。)

(4) serializable(串行化)

只要是开启了最高隔离级别的串行化,所有的事务A操作没有完成之前,所有的其他事务想要操作的同一个表,都需要排队进行阻塞,这就是串行化的场景

  • 结论:当我们将当前会话的隔离级别设置为serializable的时候,其他会话对该表的写操作将被挂起。可以看到,这是隔离级别中最严格的,但是这样做势必对性能造成影响。所以在实际的选用上,我们要根据当前具体的情况选用合适的。
  • 出现的问题:太完美了,没有一点问题,就是效率低。

面试题6. mysql中索引的类型和底层数据结构(需要在看一下)

1. MySQL的索引类型常见的有B-Tree索引、B+Tree索引、Hash索引三种主流的索引类型

  • 主键索引 (其实就是一张表的主键,主键不能为空且唯一)
  • 唯一索引 (唯一索引,就是索引的字段必须唯一,但是可以为空)
  • 普通索引 (这个就是普通的字段,没有什么限制)
  • 全文索引 (其实就是有点类似ES中的倒排索引 的全文检索,但是目前只支持英文,还不支持中文的全文索引)innodb 和Myisam都支持
  • 组合索引 (用多个列组合构建的索引,这多个列中的值不允许有空值)

2. 不同的索引引擎的实现类型:

  • Innodb
  • Myisam
  • memory(内存存储引擎),在用hash缩影的时候,哈希索引用索引列的值计算该值的hashCode,然后在hashCode相应的位置存执该值所在行数据的物理位置

3. 三种索引的底层结构:

  • B-Tree索引:其实就是一个B树,但是他的一个特点就是他的索引和数据都是在一个节点上的,这样的缺点就是,由于操作系统中的每次进行的IO的大小都是固定的页,也就是每次操作系统IO的大小只能是一页一页的进行IO,但是由于B-Tree的索引和数据都是在一起的(称为一个节点),但是每次操作系统IO的页的大小又是固定的,如果节点太大的话,那么一次IO取出来的节点就越少,IO次数就增多,效率就低了
  • 所以就有了B+Tree树的改进,他的底层就是索引和数据是分开的,也就是B+Tree的所有叶子都是数据,非叶子节点都是索引,这样的话就弥补了B-Tree的缺点,也就是每次IO的页的大小不变,但是IO的节点大小变小了(因为只有索引没有数据),所以IO的次数变小了,效率就高了
  • Hash索引:底层实现的数据结构其实就是对数据进行Hash运算,先对拿到的数据进行得到hash值(数据过多会出现hash碰撞),然后再去根据hash值去拿到需要的数据指针地址,然后拿到数据。虽然如果没有出现hash碰撞的时候效率很高,但是缺点就是不能进行范围查询。

面试题7. 数据库设计的范式知道吗?第一范式、第二范式和第三范式的区别,说的具体一些

  1. 第一范式:我理解的第一范式其实就是数据库的列不能再继续分,强调的是列的原子性
  2. 第二范式:首先是必须建立在第一范式基础上的,然后此外必须满足两个条件,第一个是必须有主键,第二个是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。其实就是消除部分依赖
  3. 第三范式:满足第二范式下,并且表中的列不存在对非主键列的传递依赖。就是不能字段A---->完全依赖于主键,但是字段B---->又完全依赖字段A,其实字段B和主键并没有太大关系,这就是依赖传递

面试题8. MySQL范式和反范式的区别以及彼此的优缺点

  • 范式的优点就是
    1)范式化的数据库更新起来更加快;

    2)范式化之后,只有很少的重复数据,只需要修改更少的数据;

    3)范式化的表更小,可以在内存中执行;

    4)很少的冗余数据,在查询的时候需要更少的distinct或者group by语句。

  • 范式的缺点:

范式化的表,在查询的时候经常需要很多的关联,因为单独一个表内不存在冗余和重复数据。这导致,稍微复杂一些的查询语句在查询范式的schema上都可能需要较多次的关联。这会增加让查询的代价,也可能使一些索引策略无效。因为范式化将列存放在不同的表中,而这些列在一个表中本可以属于同一个索引。

  • 反范式的优点:
    1)可以避免关联,因为所有的数据几乎都可以在一张表上显示;

    2)可以设计有效的索引;

    3)可以根据业务适当的做出改变

  • 反范式的缺点:
    3)表格内的冗余较多,删除数据时候会造成表有些有用的信息丢失。

面试题9. 查询中哪些情况不会使用索引?

索引失效的几种情况:https://blog.csdn.net/qq_36520235/article/details/82931885

面试题10. 说一下数据库的读写分离

面试题11. MySQL主从复制了解吗

  1. 主从复制其实就是为了减轻数据库的压力,然后以主从复制为基础,然后实现数据库的读写分离来提升数据库的并发负载压力。
  2. 其实就是主库新建一个IO线程,把数据的一些改变记录到二进制binlog日志中,然后salve服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,
  3. 如果主二进制日志中有发生改变,则从服务器开始一个I/OThread请求master二进制事件(binlog二进制文件),同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。如果发生改变,则开始一个I/OThread请求master二进制事件,同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。
    在这里插入图片描述

面试题12. 分库分表知道吗

面试题13. 多表查询怎么优化

  1. 我能想到的第一条就是不要使用子查询进行查询多表的SQL
  2. 可以只使用where的条件进行关联多表,不使用join来进行多表关联
  3. 开启数据库的缓存,然后把多表查询都拆分为单个的查询

面试题14. MySQL如何在RR隔离级别下避免幻读问题:间隙锁

面试题15. B+树和红黑树的区别、B+树和B树的区别?

B+树和B树的区别:

  1. 存储上:B树在叶子节点存储的有索引和数据都在一起,而B+树是只在叶子节点上存储的有数据,非叶子节点上只存储的有索引,所以B+树的性能比较稳定,每次查询都必须查询到叶子节点才能取到数据,而B+则不稳定有时候好的情况直接根节点就取到数据,坏的情况会在叶子节点上才能查到数据。
  2. 结构上:B树的叶子节点(也就是最下层的叶子节点的兄弟节点之间没有数据之间的联系),但是B+树在最下层的叶子节点上都是用链表的结构进行连接的,可以方便范围查询,而B树则是一次一次的进行中序遍历查询范围起始节点和末尾节点
  3. 查询性能:因为B+ 树的非叶子节点不存储数据,所以每次IO的数据会比较多,因为每次IO的最小单位的页的大小是固定的,所以每次查询出来的索引值就比较多(因为只有索引值没有数据,数据也是需要占用IO的大小的),而B树每次IO页的节点不仅有索引的值,还有数据,因为IO的页的大小固定,所以查询的节点就少。

面试题16. mysql缓存了解吗

面试题17. a Mysql中的事务是如何实现的?

  • A:原子性,通过undo log来进行实现的
  • C:一致性,其实他是通过 AID 来实现的最终一致性,只有在满足了前面三者的情况下,才有可能实现最终一致性。
  • I:隔离性,通过不同的隔离级别来实现的
    1. RAED UNCOMMITED:使用查询语句不会加锁,可能会读到未提交的行(Dirty Read);
    2. READ COMMITED:只对记录加记录锁,而不会在记录之间加间隙锁,所以允许新的记录插入到被锁定记录的附近,所以再多次使用查询语句时,可能得到不同的结果(Non-Repeatable Read);
    3. REPEATABLE READ:多次读取同一范围的数据会返回第一次查询的快照,不会返回不同的数据行,但是可能发生幻读(Phantom Read);
    4. SERIALIZABLE:InnoDB 隐式地将全部的查询语句加上共享锁,解决了幻读的问题;
    • 隔离级别原理底层的实现:
    • 使用锁
    • MVCC多版本并发控制
  • D:持久性:通过redo log来实现的
    参考:https://draveness.me/mysql-transaction/

面试题17. b Mysql中的IO次数和B+ 树的高度有什么关系?

  • 首先得需要先明确B+ 树是B 树的一种优化,优化点就是B+树中只有叶子结点才会有数据,非叶子结点存储的都是索引,但是B-树每个节点都会带有数据的,
  • B+ 树优化点1. 就是:B-树中一次io 读取的数据量大小是固定的,但是由于节点中都是有数据的,而且也会占用page的大小,所以同样的数据量大小内,B-树一次IO的读出的节点数就变少了,那么IO次数就会变多了,而B+树叶子结点是不存储数据的,数据每次IO的节点树就比较多,同样的数据量,IO次数就会比较少
  • B+树的优化点2: B树在对于范围查询的时候,查询就非常频繁,但是B+树底层的叶子结点是使用双链表来实现的,所以在进行范围查询的时候,只需要找到范围的起始位置,和结束位置,一次遍历就能查到所有的数据
  • 在使用B+树查询的时候,因为利用了磁盘的预读原理,每次IO一次其实就是一个page,这样每次一个节点只需要一次IO就能完全载入内存,所以B+树的高度越低磁盘的IO次数越少,查询性能就越高

面试题17. c 什么是聚簇索引 和 非聚簇索引?

  • 聚簇索引 和 非聚簇索引的本质区别,其实就是B+ 树的叶子结点上是不是有完整的一行数据记录。

  • InnoDB 主键使用的是聚簇索引,MyISAM 不管是主键索引,还是二级索引使用的都是非聚簇索引
    在这里插入图片描述

  • 因为Innodb其实是有主键索引和二级索引的,所以会有回表这个过程,而二级索引就是会根据你建的表的字段去找到主键,然后通过主键再去找到完成的地址,因此,innodb是聚簇索引,也就是叶子结点上存的都是数据行

  • 对于聚簇索引表来说(左图),表数据是和主键一起存储的,主键索引的叶结点存储行数据(包含了主键值),二级索引的叶结点存储行的主键值。使用的是B+树作为索引的存储结构,非叶子节点都是索引关键字,但非叶子节点中的关键字中不存储对应记录的具体内容或内容地址。叶子节点上的数据是主键与具体记录(数据内容)。

  • 对于非聚簇索引表来说(右图),表数据和索引是分成两部分存储的,主键索引和二级索引存储上没有任何区别。使用的是B+树作为索引的存储结构,所有的节点都是索引,叶子节点存储的是索引+索引对应的记录的数据。

面试题17. 事务1开启事务,查询一个表没有数据,事务2新插一条数据,并且提交,事务2再次查询是否有数据,事务1有数据吗?为什么,讲一下undo log,查询会有undo log吗?

  • 再次查询事务2能查到数据,而且事务1 也有数据。原因是:因为每个事务都是互相隔离的,当事务2提交了事务之后,其实事务2所做的操作在事务1中,也都是同样生效的。
  • undo log其实就是为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为UndoLog)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态
  • 为了保证持久性,必须将数据在事务提交前写到磁盘。只要事务成功提交,数据必然已经持久化。
    Undo log必须先于数据持久化到磁盘。如果在G,H之间系统崩溃,undo log是完整的, 可以用来回滚事务

undo log其实就是为了保证事务的原子性,当一个事务开始时会先记录一下,然后如果中间事务出现异常的话,可以利用undo log 来进行把该事务回滚到最初的状态

redo log其实简单来说就是对新的数据进行的备份,把一些已经进行commit的事务重做一遍。对于没有commit的事务,则进行处理,如果数据库宕机了可以利用redo log来保证新数据的不丢失。

面试题18. MYSQL数据库使用中什么情况下会死锁

下面列举一下常出现的三种死锁情景:

  1. 有一个用户A访问表A,已经锁住了A表,但是此时A又要去查询B表:同时用户B查询B表,而且也已经锁住了B表,此时B表也想去查询A表,由于此时A表已经被用户A锁,B表也已经用户B锁住,所以就会造成死锁。
  2. 用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A 有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种死锁比较隐蔽,但在稍大点的项 目中经常发生。如在某项目中,页面上的按钮点击后,没有使按钮立刻失效,使得用户会多次快速点击同一按钮,这样同一段代码对数据库同一条记录进行多次操 作,很容易就出现这种死锁的情况。
  3. 如果在事务中执行了一条不满足条件的update语句,则执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。类似的情 况还有当表中的数据量非常庞大而索引建的过少或不合适的时候,使得经常发生全表扫描,最终应用系统会越来越慢,最终发生阻塞或死锁

面试题19. 说一下数据库中的分布式事务的2PC(二阶提交协议)和3PC(三阶提交协议)?

https://www.hollischuang.com/archives/681

面试题20. 说一下怎么用原生的JDBC访问数据库?

  1. 第一步首先是加载jdbc的驱动程序
  2. 然后就可以从负责管理jdbc驱动的管理类DriverManager中获取数据库的实例连接对象DriverManager.getConnection()来进行获取,拿到的是一个Connection对象实例
  3. 接着是使用Connection对象来获取一个Statement对象实例,或者是PreparedStatement对象(这里有对SQL预编译功能和防止注入SQL功能)
  4. 然后是对SQL语句的执行,返回的是一个Result对象结果集
  5. 然后依次关闭数据库的连接。

面试题21. 说一下mybatis的一级缓存和二级缓冲的原理?

一级缓存简要概述: 首先一级缓存是mybatis中默认开启的,而且是只作用在SqlSession对象这个作用域中,然后SqlSession会把这个任务交给Executor执行器来去执行这个SQL语句,而缓存信息就维护在这个Executor接口中,而这个接口的实现者就是PerpetualCache这个类来通过一个大的Map来去保存这个缓存中的数据。

  • 在我们执行了(update()、delete()、insert())这几个操作的时候,那么就都会清空PerpetualCache对象的数据,但是这个PerpetualCache缓存对象还是可以继续使用的
    在这里插入图片描述
    在这里插入图片描述

一级缓存的流程前提准备:

  1. 在看下面的流程的时候,必须先知道这个维护缓存的这个大Map是怎么来进行保存已缓存的数据的。
  2. 在对于某个查询,根据statementId(MyBatis而言,你要使用它,必须需要一个statementId,它代表着你将执行什么样的Sql),params(这个就是你传入的参数),rowBounds(它通过rowBounds.offset和rowBounds.limit来过滤查询出来的结果集,这种分页功能是基于查询结果的再过滤,而不是进行数据库的物理分页)来构建一个key值,根据这个key值去缓存Cache中取出对应的key值存储的缓存结果,其实就是通过一个createCacheKey()方法,然后返回一个CacheKey 类型的key来作为map的key,value就是查询的数据值。

一级缓存的流程:

  1. 其实就是先从SqlSession中去获取这个参数(这个参数就是statementId + rowBounds + 传递给JDBC的SQL + 传递给JDBC的参数值),通过这几个值生成一个CacheKey的key
  2. 然后会通过这个key来去这个大的缓存Map中去看是不是有值,如果有直接就返回给用户了,不用直接再去和MySQL中去拿数据了
  3. 如果这个key不存在的话,那么就会从MySQL中去获取数据,然后会把根据这个不存在的key重新缓存到这个大的map中,以便下次在进行请求。
  4. 那么你该会想了 ,如果一直放到这个map中,那么这个数据肯定会越来越多啊,多到这个map都放不下,那该怎么办?
  5. 首先1. SqlSession的生存时间也不长。2. 其次就是对于这个SqlSession对象来说,如果每当执行update操作(update、insert、delete),都会对这个SqlSession的一级缓存进行清理。3. 当然你也可以进行手动的关闭这个SqlSession对象。这三点都能保证这个大Map不会无限变大。

在这里插入图片描述

二级缓存概述:

  • 二级缓存是Application应用级别的缓存,它的是生命周期很长,跟Application的声明周期一样,也就是说它的作用范围是整个Application应用

  • 由一级缓存可知一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二级缓存机制的关键就是对这个Executor对象做文章

  • 如果用户在这里配置了开启二级缓存的话(cacheEnabled=true),那么MyBatis在为SqlSession对象创建Executor对象时,会对Executor对象加上一个装饰者:CachingExecutor,

  • 这时SqlSession使用CachingExecutor对象来完成操作请求。CachingExecutor对于查询请求,会先判断该查询请求在Application级别的二级缓存中是否有缓存结果,如果有查询结果,则直接返回缓存结果;如果缓存中没有,再交给真正的Executor对象来完成查询操作,之后CachingExecutor会将真正Executor返回的查询结果放置到缓存中,然后在返回给用户。

在这里插入图片描述

注意:如果你的MyBatis使用了二级缓存,并且你的Mapper和select语句也配置使用了二级缓存,那么在执行select查询的时候,MyBatis会先从二级缓存中取输入,其次才是一级缓存,即MyBatis查询数据的顺序是:

           二级缓存    ———> 一级缓存——> 数据库

面试题22. 主键索引 和普通索引 (辅助索引) 的区别?

  • 首先在MyISAM中,由于是非聚集索引,所以主键索引和辅助索引没有本质上的区别,只是主索引要求key是唯一的,而辅助索引的key可以重复(比如说辅助索引加在的是name字段上)
    在这里插入图片描述
  • 在InnoDB数据库引擎中,InnoDB的所有辅助索引都引用主键作为data域,聚集索引(主键索引)这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录,但是有一点需要注意,就是如果走的是辅助索引的话,是需要通过主键索引再去搜索一下的,但是如果走的是主键索引的话,那么就只需要搜索一次就可以了,因为通过辅助索引查询到的知识主键的ID然后会再去通过主键ID去搜索一次
    在这里插入图片描述

面试题23. 说一下为什么使用B+,B+有什么优点(这里可以延伸为什么使用B+不用别的,可以从二叉树—>平衡二叉树(AVL)—>B Tree(多路平衡查找树)—>B+ Tree)?

自己总结的详细讲解文章:https://blog.csdn.net/qq_36520235/article/details/94317993

B+树的优点:

  1. 单次请求涉及的磁盘IO次数少(出度d大,且非叶子节点不包含表数据,树的高度小);
  2. 查询效率稳定(任何关键字的查询必须走从根结点到叶子结点,查询路径长度相同);
  3. 遍历效率高(从符合条件的某个叶子节点开始遍历即可);

B+树的缺点:

  1. B+树最大的性能问题在于会产生大量的随机IO,主要存在以下两种情况:
  2. 主键不是有序递增的,导致每次插入数据产生大量的数据迁移和空间碎片;
  3. 即使主键是有序递增的,大量写请求的分布仍是随机的;

面试题24.说一下Innodb底层是如何实现的MVCC的?

这里有大佬的总结:Innodb底层是如何实现MVCC的?

面试题25. MySQL InnoDB存储引擎中的MVCC解决了什么问题,能说下MVCC的实现原理么

面试题26. MySQL删除表操作(delete、truncate、drop的区别)

面试题27. 说一下MySQL查询过程流程解析?

图片是来自:https://blog.csdn.net/z_ryan/article/details/82262761

在这里插入图片描述

这个是MySQL的整个查询的流程,虽然不怎么问,但是了解之后,会对MySQL的认知有进一步的加深。

1、客户端同数据库服务层建立TCP连接。
2、客户端向MySQL服务器发送一条查询请求。
3、连接线程接收到SQL语句之后,将语句交给SQL语句解析模块进行语法分析和语义分析。
4、先看查询缓存中是否有结果,如果有结果可以直接返回给客户端。
5、如果查询缓存中没有结果,就需要真的查询数据库引擎层了,于是发给SQL优化器,进行查询的优化,生成相应的执行计划。
6、MySQL根据执行计划,调用存储引擎的API来执行查询
7、使用存储引擎查询时,先打开表,如果需要的话获取相应的锁。 查询缓存页中有没有相应的数据,如果有则可以直接返回,如果没有就要从磁盘上去读取。
8、当在磁盘中找到相应的数据之后,则会加载到缓存中来,从而使得后面的查询更加高效,由于内存有限,多采用变通的LRU表来管理缓存页,保证缓存的都是经常访问的数据。
9、最后,获取数据后返回给客户端,关闭连接,释放连接线程。

都来自牛客网别人的真实面试中的问题,在此真诚的感谢各位分享的大佬们

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值