索引可能有三种数据结构哈希表、有序数组和N叉树。MySQL使用了B+树。
1.哈希表(散列表)
哈希表是一种以键 – 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。
因为是使用hash算法对key求值取余得到其在数组的存储位置。
所以,哈希表这种结构适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎。在范围查询中需要全表扫描,是很慢的。
2.有序数组
有序数组在范围查询中优势非常明显,可以采用二分法,能大大缩短查询时间,尤其是数据量比较大时。时间复杂度是时间复杂度是 O(log(N))。如果往中间插入一条数据,就需要把后续数组都往后移,这个时候有序数组的成本就很高了.
所以,有序数组索引只适用于静态存储引擎,
3.二叉树(N叉树)
根据叶子节点的内容,索引类型分为主键索引和非主键索引。
主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。
非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。
基于主键索引和普通索引的查询有什么区别?
主键索引的叶子节点存的是整行数据。如果查询条件是主键就能获取整行数据。非主键索引的value是主键Id,如果查询条件是非主键,那么先查非主键索引得到主键id,根据主键Id再查主键索引得到整行数据。
从性能和存储空间方面考量,自增主键往往是比业务字段更合理的选择。可以参考:优化 | InnoDB表一定要用自增列做主键
有没有什么场景适合用业务字段直接做主键的呢?还是有的。比如,有些业务的场景需求是这样的:
只有一个索引;
该索引必须是唯一索引。
你一定看出来了,这就是典型的 KV 场景。
由于没有其他索引,所以也就不用考虑其他索引的叶子节点大小的问题。