MySQL面试题

91 阅读9分钟

1.数据库引擎有哪些,各种有什么区别:

  • 相同点:

    • InnoDB,MyISAM,Memory都支持B+树
    • MyISAM,Memory都不支持事务,不支持外键,只支持表级锁
  • 不同点:

    • InnoDB支持事务,支持外键,支持行级锁,有崩溃恢复机制
    • InnoDB默认支持B+树,MyISAM默认支持R树,Memory默认支持Hash
    • InnoDB增删改性能更优,MyISAM查询性能更优,Memory可以快速查找数据
    • InnoDB的表结构,索引,数据都存储在一个文件中;MyISAM的表结构,索引,数据都是分开存储;
    • Memory只存储了表结构,数据以key-value的形式存储在内存中
    • InnoDB支持范围查找,MyISAM支持全文索引,Memory支持精准查找

2.InnoDB和MyISAM的区别:

  • 相同点:InnoDB,MyISAM,Memory都支持B+树

  • 不同点:

    • InnoDB支持事务,支持外键,支持行级锁,不支持全文索引,有范围查找,有崩溃恢复机制,默认支持B+树;
    • MyISAM不支持事务,不支持外键,支持表级锁,没有崩溃恢复机制,默认支持R树;
    • InnoDB的表结构,索引,数据都存储在一个文件中;MyISAM的表结构,索引,数据都是分开存储;
    • InnoDB增删改性能更优,MyISAM查询性能更优

3.说说MySQL索引,以及它们的好坏

  • 索引就像指向表行的指针,它是一种帮助快速查找数据的(有序)数据结构

  • InnoDB,MyISAM,Memory都支持以B+树作为索引,其中MyISAM也支持R-树,Memory也支持Hash

  • 索引的分类:1.普通索引,2.唯一索引,3.主键索引,4.外键索引,5.全文索引,6.复合索引

  • 优点:

    • 提高数据检索效率,降低数据库的IO成本
    • 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
  • 缺点:

    • 索引列也是要占用空间的
    • 索引大大提高了查询效率,但降低了更新的速度,比如 INSERT、UPDATE、DELETE

4.B树和B+树的区别:

  • 相同点:都是多路平衡二叉树

  • 不同点:

    • B树:

      • 一个节点可以有多个key-value,并且以升序排序;查找数据时,找到key就是找到value
      • 当出现大量数据时,它的查找深度依然很深
    • B+树:

      • B树的一种变种,非叶子节点只存储key;由于非叶子结点上不包含真正的数据,所以相同内存下可以存储更多key
      • 树的所有叶子结点构成一个有序链表;因此对整个数遍历时,只需遍历叶子结点即可;有利于范围查询

4.数据库为什么不用红黑树而用B+树:

  • 红黑树:

    • 是一种近似平衡二叉树,无论是增删该查它的性能十分稳定,但红黑树的本质是二叉树,因此在数据量非常大的时候需要访问+判断的节点数比较多
    • 同时数据是存储在磁盘上的,访问需要进行磁盘IO,导致效率低;
  • B+树:

    • 是多叉的,可以有效减少磁盘IO,同时B+树增加了叶子节点间的连接,能保证范围查找时找到起点和终点后能快速取出需要的数据

5.索引怎么实现的B+树,为什么选这个数据结构:

  • 如何实现:

    • 索引的本质上就是通过预排序+树型结构来加快检索效率,而MySQL中使用InnoDB和MyISAM引擎时都使用了B+树实现索引
  • 为什么选取:

    • 在二叉查找树上查找一个数据时,当出现海量信数据时,查找效率将大大折扣
    • B+树是一种一棵平衡多路查找树,可以有效减少磁盘IO同时B+树增加了叶子节点间的连接,能保证范围查找时找到起点和终点后能快速取出需要的数据

6.聚簇索引和非聚簇索引:

分类含义特点
聚集索引(Clustered Index)将数据存储与索引放一块,索引结构的叶子节点保存了行数据必须有,而且只有一个
二级索引(Secondary Index)将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键可以存在多个
  • 聚集索引选取规则:

    • 如果存在主键,主键索引就是聚集索引
    • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
    • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引
  • 适用二级索引,都要进行二次查找

7.乐观锁和悲观锁:

  • 乐观锁:

    • 乐观锁总是假设最好的情况
    • 不加锁,在更新时判断是否在其他线程在修改
    • 适用于多读,可以使用版本号机制进行控制。
    • 优点:性能好
    • 缺点:存在成功率的问题
  • 悲观锁:

    • 悲观锁总是假设最坏的情况
    • 添加同步锁,让线程串行执行
    • 传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁
    • 优点:简单粗暴
    • 缺点:性能一般

8.MySQL为什么需要主从同步:

  • 有一句SQL语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务;使用主从复制,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运行
  • 数据备份
  • 业务量越来越大,IO访问频率过高,单机无法满足

8.MySQL主从同步是如何实现的:

  • 复制( replication )是MySQL数据库提供的一种高可用性能的解决方案,一般用于建立大型应用。

  • 工作原理分为:

    1. 主服务器( master )把数据更新记录到二进制日志( binlog )中
    2. 从服务器( slave )把主服务器的二进制日志复制到自己的中续日志( relay log )中
    3. 从服务器重做中续日志中日志,把更改应用到自己的数据库上,以达到数据的最终一致性

9.MySQL的事务隔离级别:

  • 隔离级别:

    • 读未提交( read uncommitted ):不能解决任何问题
    • 读已提交( read committed ):解决问题,脏读
    • 可重复读( repeatable read ):解决问题,脏读,不可重复读(默认)
    • 串行化( serializable ):解决问题,脏读,不可重复读,幻读
  • 存在的问题:

    1. 脏读:一个事务,读取到另一个事务中没有提交的数据
    2. 不可重复读(虚读):在同一事务中,两次读取到的数据不一样
    3. 幻读:一个事务操作(DML)数据表中的所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改
  • 注意:隔离级别从小到大安全性越来越大,但是效率越来越低

10.数据库的ACID:

  • 原子性( atomicity ):是不可分割的最小操作单位,要么同时成功,要么同时失败
  • 持久性( consistency ):当事务提交或回滚后,数据库会持久化的保存数据
  • 隔离性( isolation ):多个事务之间,相互独立
  • 一致性( durability ):事务操作前后,数据总量不变

11.说说InnoDB的MVCC:

  • MVCC( Multi-Version Concurrency Control ),即多版本并发控制
  • 它是一种用来解决读-写冲突的无锁并发控制机制,它为每个数据都根据事务维护了多个版本,使得其在并发事务中解决了读写冲突,同时使用快照读为MVCC提供非阻塞读功能
  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用堵塞读操作,提高了数据库并发读写的性能
  • 还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题
  • MVCC的具体实现:1.隐藏字段,2.undo log版本链,3.readView(读视图)

12.说说SQL优化:

  • 插入数据:批量插入,手动控制事务,主键顺序插入;对于大批量插入,load指令
  • 主键优化:主键长度尽可能短,顺序插入
  • order by优化:使用索引排序
  • group by优化:使用索引,联合索引满足最左前置法则
  • limit优化:尽量覆盖索引(查询的字段是索引字段)
  • count优化:自己计数
  • update优化:尽量使用索引更新(避免升级为表锁)
  • 如果使用了联合索引,遵守最左前缀法则

13.说说MySQL的锁:

  • 作用:在并发访问时,解决数据访问的一致性,有效性问题

    MySQL锁的分类说明
    全局锁锁定数据库中的所有表,加锁后整个实例就处于只读状态,锁的粒度小;做全库的逻辑备份
    表级锁每次操作锁住整张表,锁定粒度大,锁冲突的概念最高,并发度最低
    行级锁每次操作锁住对应的行,锁定粒度最小,锁冲突的概念最低,并发度最高
  • 表级锁分类:

    表级锁的分类说明
    表锁手动控制,分为:表共享读锁(你我只读)和表独占写锁(我全可以,你全不可以)
    元数据锁自动控制,为了避免DML(表数据增删改)与DDL(表结构增删改)冲突,保证读写的正确性
    意向锁为了避免DML在执行时,加行锁与表锁的冲突
  • 行级锁:

    行级锁分类说明
    行锁锁定单个记录的锁,防止其他事务对其行进行update和delete
    间隔锁锁定索引记录间隔,防止其他事务插入间隔
    临时锁行锁和间隔锁组合,同时锁住数据,并锁住数据前面的间隔
    • 行锁:对索引上的索引项来实现