Mysql

索引底层

索引是帮助Mysql高效获取数据的数据结构,MySQL的默认存储引擎InnoDB采用B+树来存储索引。

  • B+树阶数更多,路径更短

  • 磁盘读写代价地:非叶子节点存储指针,只有叶子结点才存储数据。

  • B+树方便扫库和区间查询

聚簇索引和非聚簇索引(二级索引)

  • 根据该索引可以查出一行数据(所有列)
  • 非聚簇索引只能查出主键,然后再根据主键查出一行数据(回表查询)

回表查询

通过二级索引找出对应的主键,再通过主键找到聚集索引中对应的整行数据,这个过程就是回表。

覆盖索引

覆盖索引:指列所有返回值都可以通过该索引查到

索引失效的几种情况

  • 违反联合索引的最左前缀原则:
  • 模糊查询时%出现在左侧:like %
  • or连接的条件两侧中有一侧没有建立索引
  • 对添加了索引的字段进行运算或者类型转换

最左前缀法则:查询从索引的最左列开始,并且不跳过索引中的列。若跳跃了某一列,后面的字段索引失效

事务的特性

  • A 原子性
  • C 一致性
  • I 隔离性
  • D 持久性

并发事务带来的问题

  • 读脏数据 :一个事务对数据进行了修改,修改的数据还没写入到数据库中,这时另一个事务也访问了这条数据,这条数据为脏数据,读脏数据
  • 不可重复读 :一个事务A多次读取同一数据,另一事务B也访问该数据,在A读数据的间隙中,B的修改导致A两次读到的数据可能不太一样。
  • 幻读 :事务A读取了几行数据,事务B插入了一些数据。在随后的查询中,事务A发现了一些原本不存在的数据,就像发生了幻觉。

如何解决并发事务带来的问题(事务隔离级别)

  • 未提交读(read uncommitted),什么都解决不了
  • 提交读(read committed),解决脏读
  • 重复读(repeatable read)默认隔离级别,解决脏读、不可重复读
  • 串行化(serializable):解决脏读、不可重复读、幻读,但性能比较低

redo log 和 undo log

  • redo log日志记录的是数据页的物理变化,服务宕机可用来同步数据
  • undo log 主要记录的是逻辑日志,当事务回滚时,通过逆操作恢复原来的数据,比如我们删除一条数据的时候,就会在undo log日志文件中新增一条delete语句,如果发生回滚就执行逆操作;

redo log保证了事务的持久性,undo log保证了事务的原子性和一致性

MVCC

事务隔离通过加锁和MVCC实现的

  • mvcc的意思是多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,它的底层实现主要是分为了三个部分,隐藏字段,undo log日志,readView读视图.

  • 隐藏字段是指:在mysql中给每个表都设置了隐藏字段,有一个是trx_id(事务id),记录每一次操作的事务id,是自增的;另一个字段是roll_pointer(回滚指针),指向上一个版本的事务版本记录地址

  • undo log主要的作用是记录回滚日志,存储老版本数据,在内部会形成一个版本链,在多个事务并行操作某一行记录,记录不同事务修改数据的版本,通过roll_pointer指针形成一个链表

  • readView解决的是一个事务查询选择版本的问题,在内部定义了一些匹配规则和当前的一些事务id判断该访问那个版本的数据,不同的隔离级别快照读是不一样的,最终的访问的结果不一样。如果是rc(read commited)隔离级别,每一次执行快照读时生成ReadView,如果是rr(repead read)隔离级别仅在事务中第一次执行快照读时生成ReadView,后续复用

主从同步原理

MySQL主从复制的核心就是二进制日志(BINLOG),它记录了所有的DDL(数据定义语言)和DML(数据操纵语言),不包括SELECT,SHOW.

  • 主库在提交事务,会把数据变更记录到binlog中
  • 从库读取主库的binlog文件,写入到从库的中继日志relaylog中
  • 从库重做relaylog中的事件,将改变自己的数据

分库分表

作用:分担访问压力,解决存储压力

  • 垂直分库:以表为依据,根据业务将不同表分到不同库中

    • 提高IO
  • 垂直分表:以字段为依据,根据字段属性将不同字段分到不同表中

    • 冷热数据分离
  • 水平分库:将一个库的数据分到不同库中 abc=a+b+c

    • 提高系统的稳定性和可用性
  • 水平分表:将一个表的数据拆分到多个表中(可以在同一个库中)

    • 优化单一表数据量过大产生的性能问题

你可能感兴趣的:(java开发面试题,Mysql,mysql,数据库)