[java复习]面试突击-mysql

潜林      2022-05-09     449

关键词:

MySQL 几大部分存储引擎、索引、事务、锁

 

MySQL的MyISAM和InnoDB存储引擎的区别是啥?

myisam,不支持事务,不支持外键约束,索引文件和数据文件分开,这样在内存里可以缓存更多的索引,对查询的性能会更好,适用于那种少量的插入,大量查询的场景。

innodb,主要特点就是支持事务,走聚簇索引,强制要求有主键,支持外键约束,高并发、大数据量、高可用等相关成熟的数据库架构,分库分表、读写分离、主备切换,全部都可以基于innodb存储引擎。

 

聊聊MySQL的索引实现原理?各种索引你们平时都怎么用的?

  • MySQL索引的原理和数据结构能介绍一下吗?
  • b+树和b-树有什么区别?
  • Myisam和Innodb存储引擎的索引实现?
  • MySQL聚簇索引和非聚簇索引的区别是什么?
  • 他们分别是如何存储的?
  • 使用MySQL索引都有哪些原则?
  • MySQL复合索引如何使用?

先说什么索引?

索引就是用一个数据结构组织某一个列数据,然后根据这一列数据查询时,不用全表扫描,根据特定数据结构找到那一列的值,然后找到对应行的物理地址。

先说b-树,画图如下:

 

 

 

查找时,从根节点开始二分查找。

b+树是b-树的变形,不一样的地方:

 

 

 

B-和B+树区别:

1. B+树只有叶子节点存储数据,其他中间节点只有索引没有数据,同样的大小的磁盘页可以容纳更多的节点元素。相同数量下,B+树更“矮胖”,查询IO次数更少

2. B+树查询必须查找叶子节点,B+树查询更稳定(并不慢)。B-树查询性能不稳定,最好只查根节点,最坏查到叶子节点。

3. B+树范围查询更简便。B+树中序遍历要简单得多

 

Myisam和Innodb存储引擎的索引实现?

myisam的索引中,每个叶子节点的data存放的是数据行的物理地址,每行对应一个物理地址。数据文件单独存放一个文件。最大特点是数据文件和索引文件是分开的。

innodb的数据文件本身就是索引文件,必须有主键,会根据主键建立一个默认索引,叫聚簇索引

innodb下,对某个非主键字段创建索引,那么最后那个叶子节点的值就是主键的值,再用主键的值到聚簇索引里查找到数据,叫回表

innodb,建议统一用auto_increment自增值作为主键,可以保持聚簇索引直接加记录,不用修改原来b+树的结构,浪费时间。

 

索引常见使用规则?

比如product表,创建索引:

create index (shop_id, product_id, gmt_create)

  1. 全列匹配

      where条件正好用到这3个字段,就用到联合索引

  2. 最左前缀匹配

      SQL里,正好用到联合索引最左边的一个或几个列表。

  3. 最左前缀匹配,但中间某个值没有匹配

      如果sql用了联合索引第一列和第三列,会按照第一列在索引里找,找完后对结果集根据第三列做全表扫描,不会走第三列的索引了。

  4. 前缀匹配

      如果不是等值,或比如=, >, <=等操作,而是Like操作。则只有Like ‘xx%’ (%在最后)这种才能用上索引。

  5. 范围匹配

      只有符号最左前缀的列的范围才用到索引,范围之后的列用不到索引。

      比如: select * from product where shop_id >= 1 and product_id = 1;

      这里就只用到shop_id索引。

  6. 包含函数

     对某个列用了函数,则该列不走索引。

 

索引缺点以及使用注意?

    常见缺点:增加磁盘消耗,占用磁盘文件,同时高并发频繁插入和修改索引,会导致性能损耗。

    使用注意:1. 尽量创建少的索引,一个表,两三个。

                       2. 一个字段的值几乎都不太一样的,比如id,这样用索引效果最好。

小结:

    互联网系统中,一般尽量降低SQL复杂度,用简单的主键索引(聚簇索引)+少数联合索引,

    可以覆盖一个表的所有SQL查询,更复杂的业务逻辑,应该放在Java代码里实现。

    SQL越简单,后面迁移,分库分表,读写分离的成本更低,减少对SQL的改造。

    MySQL最好用在在线及时存储,不要用于计算(Join, 子查询,函数等等)。高并发场景下,计算放在Java内存里

 

说说事务的几个特性是啥?有哪几种隔离级别?

特性:ACid

原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

隔离级别:

  1. 读未提交

       事务A把id=1, name=张三修改为李四,但是还未提交,这时事务B已经看到id=1的name为李四了。

  2. 读已提交(不可重复读)

      事务A把id=1, name=张三修改为李四,但是还未提交。事务B第一次读,读到是张三,看不见李四。

      紧接着事务A提交了事务,事务A在第二次读的时候,读到的是修改后的李四。

      这个也叫不可重复读,就是所谓一个事务内对一个数据的两次读,可能读到不一样的值。

  3. 可重复读

      无论事务A什么时候把张三修改为李四,事务B不管什么时刻读到值,都是事务B刚开启时读到的值。事务开启后对一行读取的值都是一样的。

      幻读(不是隔离级别):事务A第一次查询所有数据,就一行id=1。后面事务B插入一行数据id=2,事务A查询时发现2条数据,感觉发生幻觉。

                                              针对数据件数发生变化。

   4. 串行化

      事务A运行期间,事务B不允许运行。事务A提交完事务后,事务B才开始运行。串行化是为了解决幻读。

 

MySQL是怎么实现可重复读的?

    MySQL是通过MVCC机制来实现的,就是多版本并发控制(Multi-Version Concurrency Control)。

    Innodb存储引擎会在每行数据最后增加两个隐藏列

    一个保证行的创建时间,一个保存行的删除时间,但这里存放的不是时间,是事务id,事务id是mysql自己维护的自增,全局唯一。

举例1:
  id name   创建事务id   删除事务id
  1 张三     101      空
   

    事务id=101的事务查询id=1的这一行,一定能找到创建事务id<=当前事务id的一行。
    当事务id=102把id=1的一行删除了,这时id=1的行的删除事务id设置为102.

id name   创建事务id   删除事务id
1  张三     101      102


    事务id=101的事务,再次查询id=1的行,仍然能查到。因为创建事务id<=当前事务id,且当前事务id<删掉事务id。

举例2:(同一行被修改)
id   name   创建事务id   删除事务id
2  李四     201      空
2  王五     202      空

      事务201创建了id=2的数据,事务202修改了id=2的数据,把name修改为王五,这时候事务201仍然可以查询到创建事务id<=当前事务id的数据,

      查不到比自己创建事务id大的记录。


MySQL就是通过MVCC实现可重复读,事务可以读取该事务启动时创建事务id的记录,读不到后面事务的版本。

 

说说MySQL数据库锁的实现原理吗?如果死锁了咋办?

数据库锁有哪些类型?锁如何实现的?MySQL行级锁有哪两种?一定会锁指定行吗?为什么?

悲观锁和乐观锁是什么?使用场景是什么?

MySQL的死锁原理以及如何定位和解决?

 

1. MySQL锁

锁类型:表锁行锁页锁

  myisam一般加表锁,查询时,默认加共享锁,也就是表读锁,别人可以查,但不能写;

  myisam写的时候,加表独占锁,也就是表写锁,别人不能读也不能写。现在用的很少。

 

  innodb的行锁分共享锁(S)和排他锁(X)。

  共享锁,多个事务可以加共享锁读同一行数据,但别的事务不能写这行数据;

  排他锁,一个事务可以写这行数据,别的事务只能读不能写。

  innodb表锁,分成意向共享锁,就是加共享行锁的时候,必须先加这个共享表锁;

   还有一个意向排他锁,给某行加排他锁的时候,必须先给表加排他锁。这个表锁,是innodb引擎自动加的。

   insert、update、delete时,innodb会自动为这一行加行级的排他锁。

   select时,innodb啥锁都不加,默认实现可重复读,MVCC机制,所有多个事务随便读一个数据,不会有冲突,大家读的是自己的快照,不涉及锁。

  手动加共享锁

select * from table where id=1 lock in share mode; //id=1这行加了共享锁,其他事务不能修改

  手动加排他锁(悲观锁)

select * from table where id=1 for update; //id=1这行加了排他锁,表示该事务准备修改,其他事务被卡住等待。慎用!线上一般不用,容易出问题。

  乐观锁:

select id, name, version from table where id = 1;

update table set name=’new name’, version = version + 1 where id = 1 and version = 1;

  每次修改比较这条数据和之前查出的数据版本号是否一致,一致就修改并且版本号+1,否则就不更新。

  乐观锁可以提高并发访问的效率,但是如果出现了冲突只能向上抛出,然后重来一遍;悲观锁可以避免冲突的发生,但是会降低效率。 

 高并发场景用乐观锁!

  死锁:

    事务A,B对自己的资源持有锁的同时,又要去请求对方持有的锁,结果谁也拿不到锁,导致死锁。

    死锁排查,查看死锁日志,找到对应的sql,找到代码,具体判断为什么死锁。

 

MySQL的SQL调优一般都有哪些手段?你们一般怎么做?

  1. SQL慢,一般就是没有用索引。看执行计划,有没有走索引。

explain select * from table

table|type|possible_keys|key|key_len|ref|rows|extra

table: 哪个表

type: 类型  all:全部扫描  const:读常量,最多一条记录匹配  eq_ref:走主键,一般最多一条记录  index:扫描全部索引  range: 扫描部分索引  possible_keys: 显示可能使用的索引

key: 实际使用的索引

key_len: 使用索引的长度

ref: 联合索引哪一列被用到

rows: 一共扫描和返回了多少行

extra: using filesort:需要额外进行排序, using temporary: mysql构建了临时表,比如排序的时候 using where:就是对索引扫描出来的数据再次根据where来过滤出结果

 

参考资料:

互联网Java工程师面试突击(第三季)-- 中华石杉

java面试知识点突击-(81-90)

文章目录前言java知识点扫盲目录java面试知识点突击-(81-90)81建了索引但是用不上的情况?82多个独立索引和联合索引的选择?83mysql中涉及NULL容易忽略的坑?84select语句带有什么锁类型?85mysql执行计划怎么看?86事务的基本特性和隔离级... 查看详情

java面试知识点突击-(71-80)

文章目录前言java知识点扫盲目录java面试知识点突击-(71-80)71springBoot自动配置原理?72什么是嵌入式服务器?为什么要使用嵌入式服务?73mybatis的优缺点?74Mybatis与hibernate对比?75Mybatis中#和$的区别?76Mybatis的插件的运行原理,如何编... 查看详情

java面试突击-(1-10)

文章目录前言java面试突击-(1-10)01JDK、JRE、JVM什么区别02==和equals的区别03hashcode()与equals()的作用、区别和联系04重载和重写的区别05final的作用06为什么局部内部类和匿名内部类只能访问局部final变量?07String、StringBuffer,StringBuil... 查看详情

java面试知识点突击-(61-70)(代码片段)

文章目录前言java知识点扫盲目录java面试知识点突击-(61-70)61线程的生命周期,线程有几种状态?62sleep(),wait(),join()区别?63说说对线程安全的理解?64Thread、Runable的区别?65谈谈对守护线程的理解?66说说你对Threadlocal的理解?67Thr... 查看详情

新鲜出炉!2020年最新java面试题大全,面试突击必备!(代码片段)

前言发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了一套Java面试题,希望对大家有帮助哈~打算这几天每天更新15~20题。(这样有助于你们阅读和理解!)我们先从简单的开始1.JDK和JRE有什么区别?JDK:JavaD... 查看详情

java面试知识点突击-(51-60)(代码片段)

文章目录前言java知识点扫盲目录java面试知识点突击-(51-60)51spring事务的实现方式与隔离机制?51::01实现方式51::02隔离机制52spring事务的传递方式?53spring事务什么时候会失效?54并发、并行、串行的区别55并发的三大特性56为什么使用... 查看详情

面试突击:mysql中如何去重?(代码片段)

在MySQL中,最常见的去重方法有两个:使用distinct或使用groupby,那它们有什么区别呢?接下来我们一起来看。1.创建测试数据--创建测试表droptableifexistspageview;createtablepageview(idbigintprimarykeyauto_incrementcomment'自增主... 查看详情

java面试知识点突击-(91-100)(代码片段)

文章目录前言java知识点扫盲目录java面试知识点突击-(91-100)91讲一下redis的RDB和AOF机制?92redis过期键的删除策略?93redis的线程模型,为什么这么快?94Redis的string最大多少,hash、set、list、zset都分别最大多少?95Re... 查看详情

java岗大厂面试官常问的那些问题,面试突击版!

并发编程共享模型篇并发编程概览进程与线程Java线程共享模型之管程共享模型之内存共享模型之无锁共享模型之不可变共享模型之工具共享模型之管程原理之Monitor(锁)原理之伪共享模式篇—正确姿势同步模式之保护性智停同步... 查看详情

耗时4个月,阿里架构师打造java面试突击文档,10位朋友已拿offer

...司以及要应聘的岗位提前准备技术面试面试之前做好定向复习面试之后复盘如果你在面试之前没有准备充分的话,这样就没有办法给面试官留下一个好印象,我这边也有整理好的准备文档,有需要的可以私信我获取到... 查看详情

突击java面试-分布式搜索引擎的架构原理

1面试题说说ES的分布式架构原理2考点分析在搜索这块,曾经lucene是最流行的搜索库.几年前业内一般都问,你了解lucene吗?你知道倒排索引的原理吗?但现在不问了,因为现在项目基本都是采用基于lucene的分布式搜索引擎——Elasti... 查看详情

java程序员被裁员,突击面试4家大厂,斩获2家offer~

总结面试了知乎/快看漫画/快手/头条四家公司,拿到了其中两家offer感觉面试难度整体比校招简单一些,可能是由于有正式项目经历了,基础知识问的少了些感觉今年行情不大好,不过好好准备还是能得到心仪的offer二年没面试... 查看详情

java面试突击-(31-40)

文章目录前言java面试突击-(31-40)31不建议使用LinkedList的原因?32HsahMap和HashTable的区别?33HsahMap的底层实现是什么?34HsahMap的底层数组的扩容机制?35concurrentHashMap的原理是什么?36concurrentHashMap怎么保证读的时候不加锁?37list的底层实现38... 查看详情

创优视觉程序员如何有效准备java面试

...面试题,有两个好处:  1、找出高频面试题,知道如何复习;  2、查漏补缺,找出问题所在 查看详情

java程序设计第三版课后答案,面试突击版!

1基础为什么Java中只有值传递?int范围?float范围?hashCode与equals,什么关系?StringStringBuffer和StringBuilder的区别是什么?String为什么是不可变的?Java序列化中如果有些字段不想进行序列化怎么办?构... 查看详情

java面试突击-(11-20)

文章目录前言java面试突击-(11-20)11详细的说一下抽象类和接口的区别?11::01设计目的区别:11::02概念区别:11::03使用区别:12说一下类和对象的关系?13面向对象四大特征?14什么是字节码,采用字节码的优势?14::01前提准备:14::02什么是... 查看详情

mysql面试复习总结

三范式三范式定义(范式和反范式)1NF:每个数据项都是最小单元,不可分割,确定行列之后只能对应一个数据。2NF:每一个非主属性完全依赖于候选码(属性组的值能唯一的标识一个元组,但是其子集不可以)。?3NF:每一个... 查看详情

耗时4个月,阿里架构师打造java面试突击文档,10位朋友已拿offer

不论是校招还是社招都避免不了各种面试、笔试,如何去准备这些东西就显得格外重要。不论是笔试还是面试都是有章可循的,我这个有章可循”说的意思只是说应对技术面试是可以提前准备。运筹帷幄之后,决胜千... 查看详情