面试漫谈(十一)- 数据库篇

Posted by YiBo on December 18, 2020

MyISAM 和 InnoDB 的区别

数据库引擎 事务 外键 索引 count
InnoDB 支持 支持 聚集索引 全表扫描 行锁
MyISAM 不支持 不支持 非聚集索引 变量 表锁

mysql什么情况下索引失效

  • where is null 全表扫描
  • where !=, <> 全表扫描
  • where 中 or ,如果俩个字段有一个没有索引,就会全表扫描
  • where 后面跟表达式,函数操作,%like
  • 如果索引列是字符串要加”“,如果是数字不要加”“

mybatis是否看过源码,mybatis的原理

框架整体设计分为

  • 接口层

  • 数据处理层

    参数映射 —》 SQL解析 —》SQL执行 —》结果处理和映射

  • 框架支撑层

    SQL语句配置方式–》基于XML / 注解

    事务管理

    连接池管理

    缓存机制

  • 引导层

    基于XML配置方式,基于Java API方式

Mybatis 工作原理

  1. 读取MyBatis配置文件
  2. 加载映射文件,及SQL映射文件,在mybatis-confic.xml
  3. 构建会话工程 SqlSessionFactory
  4. 创建会话对象 SqlSession
  5. Executor执行器,会根据SQLSession传递的参数动态的生成需要执行的SQL语句,同时负责查询缓存的维护
  6. MappedStatement对象,在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的ID,参数等信息
  7. 输入参数映射
  8. 输出参数映射

mybatis分页插件原理

编写一个针对statementHandler的query方法拦截器,然后获取到SQL,对SQL进行重写增强

MYBATIS获取插入记录的自增ID

在mapper中指定keyProperty属性

mybatis最终通过mysql驱动程序获取到了新添加的记录主键值

jdbc3KeyGenerator中,getGeneratedKeys

分库分表了解吗

水平切分,主键策略是snowFlake,分片策略采用一致性哈希分片

B+Tree

结构:

  • 非叶子节点不存储data数据,只存储索引值,便于存储更多的索引值
  • 叶子节点包含了所有的索引值和data数据
  • 叶子节点用指针链接,提高区间的访问性能

为什么选择b+Tree

InnoDB需要支持的场景和功能需要再特定查询上拥有较强的性能

联合索引问题

https://blog.csdn.net/houmenghu/article/details/109580196

回表查询

https://www.cnblogs.com/myseries/p/11265849.html

image-20210104123356727

  • 索引覆盖

    create table user (
        id int primary key,
        name varchar(20),
        sex varchar(5),
        index(name)
    )engine=innodb;
      
    select id,name from user where name='shenjian';
      
    # 能够命中name索引,索引叶子节点存储了主键id,但sex字段必须回表查询才能获取到,不符合索引覆盖,需要再次通过id值扫码聚集索引获取sex字段,效率会降低。
    select id,name,sex from user where name='shenjian';
      
      
      
    create table user (
        id int primary key,
        name varchar(20),
        sex varchar(5),
        index(name, sex)
    )engine=innodb;
      
    # 都能够命中索引覆盖,无需回表。
      
    select id,name ... where name='shenjian';
       
    select id,name,sex ... where name='shenjian';
      
      
    # 全表count查询优化
    select count(name) from user;
    alter table user add key(name); # 能够利用索引覆盖