索引基本概念
索引是榜示 mysql 高效获取数据的排好序的数据结构,存储在文件里面
索引结构
二叉树
红黑树
HASH
做一次 hash 算法,得到的值作为 key 地址进行存储;但是也存在 hash 冲突问题,不连续性导致不支持范围查询
BTree
遵循左小右大,有度的概念——分裂阈值,一个叶子节点最多存储的数量

可以控制纵向高度,以 key-value 的形式进行存储,叶子节点中的数据 key 从左到右递增排列;存储内存的最小单位:页(4k);进行范围查找需要重复扫描
B+Tree
非叶子节点只存储索引,叶子节点包含所有数据;叶子节点之间有指针连接,范围查找可直接使用指针,提高区间访问的性能

BTree 与 B+Tree 的区别
- BTree 节点存储索引和整条数据的内存地址;B+Tree 非叶子节点只存储冗余索引,叶子节点直接存储索引和其他数据
BTree 叶子节点不存在指针指向,范围查找需重复扫描;B+Tree 叶子节点有指针指向,可直接获取范围数据(mysql 底层优化为双向指针)
聚集索引与非聚集索引
聚集索引:索引和数据聚集在一起:设计 innoDB 引擎的表,主键索引和数据存储在一起
- 非聚集索引:InnoDB 的一般索引和设计 MyISAM 引擎的表,因为索引文件和数据文件是分离的
MyISAM 索引实现

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

磁盘中存在.frm/.ibd文件;数据文件本身就是索引文件,按照 B+Tree 组织的一个索引结构文件;叶子节点包含了完整的数据非主键索引结构叶子节点存储主键值:一致性和节省存储空间(通过非主键索引获取到主键索引值,再通过主键索引检索数据,这就是所谓的
回表)
InnoDB 和 MyISAM 的区别
- innodb 支持事务,myisam 不支持事务
- innodb 支持外键,myisam 不支持外键
- myisam 支持表级锁(不支持高并发,已读为主),innodb 支持行锁,粒度更小
- 执行大量查询,最好选择 muisam,执行大量新增、更新,最好选择 innodb
- innodb使用聚集索引,索引和数据存放在一个文件;myisam使用非聚集索引,存储三个文件:表定义,表数据,表索引
为什么说 MyISAM 查询要比 InnoDB 快
并不一定,具体看场景;
InnoDB 根据索引查询到的是数据块,还要在定位到具体的行,还要维护 MVCC 一致;MyISAM 本身不支持事务;从这些方面来讲,MyISAM 查询要比 InnoDB 快
为什么要使用主键并推荐使用整型自增主键?
- 在没有主键的情况下,mysql 会选出一个字段来作为主键;若还是没有合适的字段来作为主键,mysql 会生成一个整型的
隐式主键;但自己就可以做得事情尽量不要交给 mysql 来做 - 自增是保证有序;若是无序主键,在维护 B+Tree 结构时,涉及节点的分裂和自动平衡,有序则直接开辟新空间即可
拿 uuid 举反例,整型的数据肯定是要比字符串的数据容易进行比较,再有数据插入的情况下,整型主键维护磁盘文件更方便,更高效
联合索引的底层数据结构
主键索引与唯一索引的区别
主键索引一定是唯一索引,唯一索引不一定是主键索引;主键是一种约束,唯一索引是一种索引;
- 主键列不允许空值,唯一索引允许有空值;
- 主键索引一张表最多只能有一个,但可以创建多个唯一索引;
- 都可以提高查询效率,但执行优先于主键;


