- 什么是索引
- 索引的好处
- 索引的坏处
- 创建索引的三种方式
- 索引类型
- 索引数据结构
- Hash表
- B树
- B+树
- B树和B+树的区别
- B+树的最大优点
- 面试题
- 为什么索引结构默认使用B+树,而不是B-Tree,Hash哈希,二叉树,红黑树?
- 聚簇索引
- 非聚簇索引
- 聚簇索引和非聚簇索引的区别
什么是索引
数据库中索引(Index)是一种帮助快速查找数据的数据结构,可以把它理解为书的目录,通过索引能够快速找到数据所在位置。
索引的好处
-
使用索引可以加快数据查找的效率,这是创建索引的最主要原因。
-
场景的索引数据结构有:Hash表(通过hash算法快速定位数据,但不适合范围查询,因为需要每个key都进行一次hash)、二叉树(查找和修改效率都比较高),但是在InnoDB引擎中使用的索引是B+Tree,相较于二叉树,B+Tree这种多叉树,更加矮宽,更适合存储在磁盘中。
-
通过创建唯一性索引,可以保证数据表中每一行数据的唯一性。
索引的坏处
使用索引增加了数据查找的效率,但是相对的由于索引也需要存储到磁盘,所以增加了存储的压力,并且新增数据时需要同步维护索引。但是合理的使用索引能够极大提高我们的效率!
创建索引的三种方式
-
在执行create table时创建索引
create table user_index( id int auto_increment primary key, first_name varchar(16), last_name varchar(16), id_card varchar(18), information text(225), key name( first_name,last_name), fulltext key(information), unique key(id_card));
-
使用alter table添加索引
alter table table_name add index index_name(column_list);
-
使用create index命令创建索引
create index index_name on table_name(column_list);
索引类型
-
普通索引
create index index_name on table_name(column_list);
-
唯一索引
create index index_name on table_name(column_list);
-
主键索引
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) )
-
组合索引
ALTER TABLE `table` ADD INDEX name_city_age (name,city,age);
-
全文索引
索引数据结构
Hash表
Hash索引不支持顺序和范围查找。
B树
B树是平衡的多叉搜索树。
B+树
为了提高查找速度,其常用的数据结构是一个N叉搜索树。
B树和B+树的区别
-
B 树的所有节点既存放键(key) 也存放 数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。
-
B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。
-
B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节点到叶子节点的过程,叶子节点的顺序检索很明显。
B+树的最大优点
-
非常善于范围查找
-
所有的查询最终都是落在叶子结点上,查询速度树比较稳定的。
-
由于叶子结点是数据的全集,因此就可以把叶子结点存到硬盘上,非叶子结点直接存到内存中,又进一步的大大降低了读取硬盘的次数。
面试题
为什么索引结构默认使用B+树,而不是B-Tree,Hash哈希,二叉树,红黑树?
- Hash哈希,只适合等值查询,不适合范围查询。还会产生哈希冲突。
- 一般二叉树,可能会特殊化为一个链表,相当于全表扫描。
- 红黑树,是一种特化的平衡二叉树,MySQL 数据量很大的时候,索引的体积也会很大,内存放不下的而从磁盘读取,树的层次太高的话,读取磁盘的次数就多了。
- B-Tree,叶子节点和非叶子节点都保存数据,相同的数据量,B+树更矮壮,也是就说,相同的数据量,B+树数据结构,查询磁盘的次数会更少。
综上,索引更适用于查找多,修改少的场景。
聚簇索引
叶子结点同时存放索引和数据。注意:聚簇索引中叶子节点存储的是行数据。
非聚簇索引
索引和数据分开存放。在叶子节点中存放的是数据行的主键索引。通过非聚簇索引进行查询,会先得到一个主键ID,之后再使用主键ID去聚簇索引中的叶子节点查找数据行。
聚簇索引和非聚簇索引的区别
两者主要的区别是存储数据的不同。
- 聚簇索引叶子节点存储的是行数据;而非聚簇索引叶子节点存储的是聚簇索引(通常是主键 ID)。
- 聚簇索引查询效率更高,而非聚簇索引需要进行回表查询,性能不如聚簇索引。
- 聚簇索引一般为主键索引,而主键一个表中只能有一个,因此聚簇索引一个表中也只能有一个,而非聚簇索引则没有数量上的限制。