一、 从物理角度
- 聚簇索引
- 非聚簇索引
二、 从逻辑角度
- 主键索引 (他是一种特殊索引,不允许有空值,一般在建表时同时创建)
- 普通索引 (最基本的索引,没限制)
- 多列索引 (复合索引 多个字段上建立索引遵循“”最左前缀匹配“”)
- 唯一索引 (索引列必须为空,唯一,允许有空值,如果是组合索引则组合必须唯一)
- 空间索引(对空间数据类型建立的索引)
三、从数据结构的角度
- B+树索引 (时间复杂度为,(O(logn)))
- hash 索引 (只有Memory引擎支持)
- FUll TEXT 索引 (MyISM,InnoDB 支持)
- R-Tree索引 (=空间索引 可以忽略)
下面着重介绍下 ,从物理角度划分的 (聚簇索引、非聚簇索引)。和从数据结构角度划分的(B+Tree 索引, 和Hash索引)
首先要明白索引( index)是在存储引擎(storage engine)层面实现的,而不是在serverc层面实现的,不是所有的存储引擎都支持所有索引类型,即使多个存储引擎支持某一个索引类型他们的实现和行为也有所差别。
聚簇索引
聚簇索引也叫簇类索引,是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。由于聚簇索引的索引页面指针指向数据页面,所以使用聚簇索引查找数据几乎总是比使用非聚簇索引快。每张表只能建一个聚簇索引,并且建聚簇索引需要至少相当该表120%的附加空间,以存放该表的副本和索引中间页。
非聚簇索引
非聚簇索引记录的物理顺序与逻辑顺序没有必然的联系,与数据的存储物理结构没有关系;一个表对应的非聚簇索引可以有多条,根据不同列的约束可以建立不同要求的非聚簇索引。
B-Tree索引
一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node ,而且从根节点到任何一个 Leaf Node 的最短路径的长度都是完全相同的。它的所有的值(被查找的列)都是排序的,所以B-Tree索引适合查找某一范围内的数据,而且支持数据排序(ORDER BY).
当然,可能各种数据库(或 MySQL 的各种存储引擎)在存放自己的 B-Tree 索引的时候会对存储结构稍作改造。
如 Innodb 存储引擎的 B-Tree 索引实际使用的存储结构实际上是 B+Tree ,也就是在 B-Tree 数据结构的基础上做了很小的改造,在每一个Leaf Node 上面出了存放索引键的相关信息之外,还存储了指向与该 Leaf Node 相邻的后一个 LeafNode 的指针信息,这主要是为了加快检索多个相邻 Leaf Node 的效率考虑。
MYISAM 为了节省空间对索引进行了压缩,从而牺牲了性能。
Hash索引
当我们在给某张表某列升增加Hash索引时,将对这张表的这一列 进行哈希算法的相关计算,得到哈希值,排序在哈希数组上,所以Hash索引可以一次定位,效率很高。
但它有很多缺点
- 因为Hash索引比较的是经过Hash计算的值,所以只能进行等式的比较,不能用于范围查询。
- 每次都要全表扫描。
- 由于哈希值是按顺序排序的,但是哈希值映射的真正数据在哈希表中就不一定按照顺序排列。所以无法利用hash索引加速任何排序操作。
- 不能用部分索引键来搜索,因为组合索引在计算Hash值时一起计算。
- 当哈希值大量重复,且数据量大时,其检索效率没有B-Tree索引高。
目前只有Memoey 引擎支持显式的hash索引,但它的hash值不唯一,冲突太多会影响查找性能。
Memory 引擎默认就为Hash 索引, 虽然它也支持 B-Tree 索引。