张三求职日记--面试题篇--mySql

30 阅读5分钟

张三求职日记--面试题篇--mySql封面图.jpg

mysql底层数据结构

通常mysql的存储引擎分为myisam和innodb,两者底层的数据结构都是B+树。
通常B+树的层高比较低,每个叶子节点默认能存储16KB数据

为什么使用B+树

为了尽可能的存储更多的数据,并减少查询次数,传统的二叉树是不够用的,需要引入多叉树的概念,于是有了多路平衡搜索树的B树。
而B+树在B树的基础上更进一步,只在叶子节点上存储数据,在非叶子节点存储索引,可以进行更快的查询,并且范围搜索效果好。
值得一提的是,较为火热的非关系型数据库redis底层使用的是跳表,也是很优秀的存储实现,B+树与跳表适合不同的场景,后面整理redis的时候详细说。

什么是索引

索引相当于字典的目录,是一种用于快速定位和检索数据的数据结构,通常索引底层通常也还是二叉树,非叶子节点存储索引的key,叶子节点存储数据主键或真实数据。
索引能加快数据的查询效率,但是索引本身也会占用存储空间,数据变化后索引也会发生变化,因此不要滥用索引。

通常什么样的数据需要建索引

通常通过它经常需要进行查询的数据并且区分度高的数据需要建立索引,比如说订单号、商品ID等,区分度低的数据不要去建索引,比如说性别。
另外如果数据经常需要更新,尽可能不要创建索引。表规模较小或者列存储的数据是长文本、也不适合创建索引。

如何实现事务

对于mysql来说是通过START TRANSACTION语法,结合mysql底层的undo log机制来实现的,如果两条语句不能同时完成,则会进行回滚数据(同时失败)。
对于代码实现来说,一般是通过spring的@Transactional注解去实现的。

事务的传播行为

  1. REQUIRED:默认的隔离级别,如果当前存在事务则加入,否则创建新事务,适合绝大部分业务。
  2. SUPPORTS:如果当前存在事务则加入,否则已非事务方式执行,适合可非事务执行的查询方法。
  3. MANDATORY:必须在事务中调用,否抛出异常。
  4. REQUIRES_NEW:始终创建新事务,挂起当前事务,适合需独立执行的业务比如说记录日志。
  5. NOT_SUPPORTED:强制非事务执行,挂起当前事务。
  6. NEVER:禁止出现事务,否则跑出异常。
  7. NESTED:嵌套事务,基于保存点实现。

事务的隔离级别以及解决了什么问题

  1. 默认:与数据库有关,mysql为可重复读,oracle为读已提交。
  2. 读未提交:允许读取未提交的数据,有可能出现脏读(读取到其他事务未提交的修改)的风险。
  3. 读已提交:可避免脏读,但可能会有不可重复读(同一事务内多次读取不一致的的问题)的问题。
  4. 可重复读:可解决不可重复读问题,但可能发生幻读(两次范围读取数据数量不一致)的问题。
  5. 串行化:可解决所有问题,但是性能低。 如果既能解决幻读问题,又能保证性能?
  • 可通过间隙锁实现

什么情况下事务会失效

  1. 非pubilc方法的事务注解
  2. 类中的内部方法调用配置了事务的方法
  3. 异常捕获后未抛出
  4. 传播行为冲突
  5. 异步方法的事务会失效
  6. 数据库不支持或注解使用错误

什么是MVCC

MVCC是多版本并发控制,通过MVCC的三种log可实现数据库的众多功能如事务、回滚、主从同步。
MVCC通过维护数据的多个历史版本,并结合事务ID和快照机制,实现高效、非阻塞并发控制的核心数据库技术。
三种log:undo log,redo log,bin log
undo log:InnoDB特有,主要用于事务失败回滚,undo log会记录一条与执行sql相反的记录,以保证能还原会原始数据
redo log:InnoDB特有,记录事务对数据的修改操作,用于崩溃后数据恢复,保证持久性。写redo log采用WAL技术,将数据预写入日志,再写入磁盘
binlog:mysql实现,主要用于主从复制和数据恢复,支持STATEMENT、ROW、MIXED三种格式

通过什么机制实现主从同步

主要通过binlog实现主从同步
主库将数据变更写入到binlog中,从库启动IO线程拉取binlog并写入relay log中,读取relay log重放数据库操作

怎么实现分库分表

核心思路是进行垂直拆分或者水平拆分
垂直拆分:

  1. 可根据实际业务情况将不同的业务表拆到不同的数据库中
  2. 可根据实际业务情况把表的列拆到不同表中,比如拆为基础表和详情表

水平拆分:

  1. 可把表数据表拆到不同的数据库中,比如说core_1,core_2中都有此表
  2. 可把表数据拆到不同的表中,比如说把表按年份拆成不同名字相同列的表

通常情况下分库分表需要动态进行,新业务同时写入新旧分片,旧分片数据逐步迁入新业务中,完整迁移完成后逐步将写入请求转入新分片并停止旧分片的写入

如何分析慢sql问题

  1. 捕获慢sql--一般DBA会给出
  2. 通过EXPLAIN语句分析sql的执行计划
  3. 通过可能的问题点结合业务分析解决方案

通常导致慢sql的问题:

  1. 缺少索引
  2. 索引失效,常见问题:字段参与计算、数据发生了隐式类型转换、违反最左前缀原则、范围查询、左模糊查询、or关键字、not in/!=关键字
  3. 分页深度过大
  4. 多表关联查询慢(可改为子查询)