索引和事务

MySQL数据库有三个非常重要的概念,分别是索引、事务、锁。这些也都是面试中的热点问题,在此做以总结,也方便面试前的回顾。

索引

索引的概念

简单来说,索引是一种排好序的数据结构。这里面包含两个信息,一个是索引是排好序的,另一个是索引本质上是一种数据结构。

  • 排好序的

    我们知道MySQL数据库的数据都是按页存储在数据库中的,查询页面中的数据的时候需要从磁盘将这个页面读取到内存中,然后再在内存中继续寻找所需要的数据。这就存在一个问题,磁盘IO是相当慢了,我们要尽可能的减少IO的次数,因此需要准确的找到数据所在的页面才是关键,而索引的产生加快了检索速度。

    数据页之间是通过双向链表按照主键值的大小排好序的,数据页内部的每一条记录都按照主键值的大小排好序的。

  • 是一种数据结构

    索引采用的数据结构是B+树。为了减少IO次数,需要树的高度间可能的低,B树和B+树都应用在磁盘IO的数据结构,但是B树的非叶子节点存储是数据记录,而B+树的非叶子节点存储的是索引值,所以B+树的非叶子阶段存储的比B树的多,所以B+树比B树更低,磁盘IO更少。

    B+树的优势:

    • 磁盘IO次数更少。
    • 查询复杂度都是树的高度,查询时间比较稳定
    • 由于叶子节点用链表连接,适合于范围查询。

索引的存储方案

InnoDB和MySIAM两种存储引擎索引的存储方式是不同的,InnoDB采用的是聚簇索引,而MySIAM采用的是非聚簇索引。

  • InnoDB的存储方案

    InnoDB的索引和数据是存储在一个文件中的,主键采用的是聚簇索引,非主键采用的是辅助索引,也叫二级索引。InnoDB会根据主键构建B+树,树的叶子节点存储的用户的全部的数据,索引会根据主键值的大小将数据页和数据之间排好序。

  • MySIAM的存储方案

    MySIAM的索引和数据是存储在不同的文件中的。对主键单独创建索引,索引的叶子节点记录的是索引值和数据文件的行号,对非主键创建的是二级索引。

索引的优化

事务

事务的四大特性ACID

  • 原子性

    原子性指的是在一个事务内,所有的操作要么都执行,要么都不执行。如果里面的一条sql语句出现了异常,则执行的语句都需要回滚。实现原理: 原子性是用undolog日志来实现的,每次执行对数据库的修改操作,都会记录在日志中,如果事务发生了回滚,则根据这个日志进行数据重放。

  • 一致性

    一致性指的事务执行前后数据的合法性不变。比如转账前后双方的余额和是一样的。一致性需要数据库和业务共同的维护

  • 隔离性

    并发执行的事务之间是相互隔离的。并发执行的事务有四个隔离级别。分别是读未提交,读已提交,可重复读,序列化。

  • 持久性

    持久性指的是对数据库的改变是永久的,即使数据库宕机了,恢复之后数据还应该在。实现原理:数据库的数据是存放在磁盘中的,为了减轻IO负担,实现持久性是用的是redolog日志,对数据库的修改操作会存放在redolog日志,等到空闲的时候会将日志的操作持久化磁盘中的。

事务的隔离级别

  • read uncommitted 可以读取到其他事务未提交的内容 --->避免不了脏读
  • read committed 只可以读取其他事务已经提交的内容
  • repeatable-read(MySQL默认) 可以重复读取本次事务,数据的值不会发生变化,当再次更新的时候会按照实际数据的值来计算
  • serializable

MVCC

MVCC是多版本并发控制,主要是依靠聚簇索引中的两个隐藏列和undo log日志来实现的,多个事务每次对某条记录修改的时候都会生成对应的undo log,每一条undo log中也有两个必要的属性,分别是生成该日志的事务id和一个指向上一个版本的日志的指针。事务对记录进行查询的时候,就需要遍历版本链,在版本链上找出自己可见的版本,这个需要借助ReadView,ReadView维护着当前系统中还活跃的事务id的一个列表。那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问。读已提交和可重复读的区别就在于生成ReadView的时机不同,读已提交是在每次Select都会生成一个ReadView,而可重复读是在第一次Select之前生成一个ReadView,之后再也不生成了。

posted @ 2020-07-11 21:02  earth腾飞  阅读(398)  评论(0编辑  收藏  举报