索引是什么
索引好比一本书的目录,能够快速的找到想要的内容。访问数据可以通过两种方式: 一 顺序访问,逐条遍历,效率不高 ,二 索引访问,可以高效的访问到需要的数据
如下图所示
mysql 索引分类
按数据结构分类: B+tree 索引、Hash索引、Full-text索引
按物理存储分类: 聚簇索引、二级索引(辅助索引)
按字段特性分类:主键索引、普通索引、前缀索引
按字段个数分类:单列索引、联合索引(复合索引)
查看 MySQL 索引情况,版本 8.0.21 ,引擎 InnoDB
索引类型与索引方法的区别
很多博客解释的与实际操作看到的有锁不同,版本的不同导致mysql 支持的索引类型有所区别,索引方法可以理解为具体的索引实现方式,索引本身也是一种数据结果。
索引类型理解为改索引的实现的目的
索引类型
- normal 普通索引,提高查询效率
- unique 唯一索引,保在索引列唯一
- fulltext 全文索引
- spatial 空间索引,通过R数实现,多为空间索引高效
索引方法
- btree
- hash
| \ | normal | unique | fulltext | spatia |
|---|---|---|---|---|
| btree | ✔ | ✔ | ||
| hash | ||||
| 空 | ✔ | ✔ |
MyISAM索引实现
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM索引的原理图:
这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:
同样也是一棵B+树,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。
InnoDB索引实现
虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。
第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整型。
第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。例如,上图为定义在Col3上的一个辅助索引:
这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一棵B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
索引的分类
Mysql 中索引的类型
- normal
- fulltext
- spatial
- unique
其中的区别:
normal : 普通索引,表示普通索引,大多数情况下都可以使用
unique: 唯一索引,表示唯一的,不允许重复的索引,如果改字段保证不会重复,则可以设为 unique
full text :全文索引: 表示全文搜索,在检索长文本效果最好。如果短文本则使用普通的 index 也可以
spatial : 空间索引 ,只能在存储引擎 MyIsam 中创建,是为空间数据类型字段建立的索引,mysql 中的空间数据类型有四种: geometry , point , linestring, polygon
Mysql 中索引的方法
- BTREE
- HASH
Btree 类型的索引: Btree 又称为 b+ 树
- B-TREE索引在范围查找的SQL语句中更加适合(顺序存储)
- B-Tree索引可以被用在像=,>,>=,<,<=和BETWEEN这些比较操作符上。而且还可以用于LIKE操作符,只要它的查询条件是一个不以通配符开头的常量
- innodb和myisam存储引擎不能使用hash索引........原因: Innodb 存储引擎支持的哈希索引是自适应的,Innodb 存储引擎会根据表的使用情况自动为表生成哈希索引,不能人为干预是否在表中生成哈希索引。
Hash 索引:
- Hash索引基于Hash表实现,只有查询条件精确匹配Hash索引中的所有列才会用到hash索引
- 存储引擎会为Hash索引中的每一列都计算hash码,Hash索引中存储的即hash码,所以每次读取都会进行两次查询
- Hash索引无法用于排序
- Hash不适用于区分度小的列上,如性别字段
- hash索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询. 比如< , 由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,
- 因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样
参考:https://www.cnblogs.com/boothsun/p/8970952.html
树模拟:https://www.cs.usfca.edu/~galles/visualization/RedBlack.htm