索引基本概念

索引是榜示 mysql 高效获取数据的排好序的数据结构,存储在文件里面

索引结构

二叉树

左叶子节点小,右叶子节点大
image.png
极端情况:相当于顺序寻找

红黑树

平衡二叉树,会自动平衡数据
image.png
数据量越大,树的深度也越大

HASH

做一次 hash 算法,得到的值作为 key 地址进行存储;但是也存在 hash 冲突问题,不连续性导致不支持范围查询

BTree

遵循左小右大,有度的概念——分裂阈值,一个叶子节点最多存储的数量
image.png
image.png
可以控制纵向高度,以 key-value 的形式进行存储,叶子节点中的数据 key 从左到右递增排列;存储内存的最小单位:页(4k);进行范围查找需要重复扫描

B+Tree

非叶子节点只存储索引,叶子节点包含所有数据;叶子节点之间有指针连接,范围查找可直接使用指针,提高区间访问的性能
image.png
image.png
BTree 与 B+Tree 的区别

  1. BTree 节点存储索引和整条数据的内存地址;B+Tree 非叶子节点只存储冗余索引,叶子节点直接存储索引和其他数据
  2. BTree 叶子节点不存在指针指向,范围查找需重复扫描;B+Tree 叶子节点有指针指向,可直接获取范围数据(mysql 底层优化为双向指针)

    聚集索引与非聚集索引

  3. 聚集索引:索引和数据聚集在一起:设计 innoDB 引擎的表,主键索引和数据存储在一起

  4. 非聚集索引:InnoDB 的一般索引和设计 MyISAM 引擎的表,因为索引文件和数据文件是分离的

    MyISAM 索引实现

    image.png
    磁盘中存在.frm/.MYD/.MYI文件;查询顺序:索引—文件指针—数据文件

    InnoDB 索引实现

    image.png
    磁盘中存在.frm/.ibd文件;数据文件本身就是索引文件,按照 B+Tree 组织的一个索引结构文件;叶子节点包含了完整的数据

    非主键索引结构叶子节点存储主键值:一致性和节省存储空间(通过非主键索引获取到主键索引值,再通过主键索引检索数据,这就是所谓的回表

InnoDB 和 MyISAM 的区别

  1. innodb 支持事务,myisam 不支持事务
  2. innodb 支持外键,myisam 不支持外键
  3. myisam 支持表级锁(不支持高并发,已读为主),innodb 支持行锁,粒度更小
  4. 执行大量查询,最好选择 muisam,执行大量新增、更新,最好选择 innodb
  5. innodb使用聚集索引,索引和数据存放在一个文件;myisam使用非聚集索引,存储三个文件:表定义,表数据,表索引

    为什么说 MyISAM 查询要比 InnoDB 快

    并不一定,具体看场景;
    InnoDB 根据索引查询到的是数据块,还要在定位到具体的行,还要维护 MVCC 一致;MyISAM 本身不支持事务;从这些方面来讲,MyISAM 查询要比 InnoDB 快

为什么要使用主键并推荐使用整型自增主键?

  1. 在没有主键的情况下,mysql 会选出一个字段来作为主键;若还是没有合适的字段来作为主键,mysql 会生成一个整型的隐式主键;但自己就可以做得事情尽量不要交给 mysql 来做
  2. 自增是保证有序;若是无序主键,在维护 B+Tree 结构时,涉及节点的分裂和自动平衡,有序则直接开辟新空间即可
  3. 拿 uuid 举反例,整型的数据肯定是要比字符串的数据容易进行比较,再有数据插入的情况下,整型主键维护磁盘文件更方便,更高效

    联合索引的底层数据结构

    遵循最左前缀原则
    image.png

    主键索引与唯一索引的区别

  4. 主键索引一定是唯一索引,唯一索引不一定是主键索引;主键是一种约束,唯一索引是一种索引;

  5. 主键列不允许空值,唯一索引允许有空值;
  6. 主键索引一张表最多只能有一个,但可以创建多个唯一索引;
  7. 都可以提高查询效率,但执行优先于主键;