# 索引 ## 定义 **索引**是帮助MySQL高效获取数据的**排好序**的**数据结构** ## 索引分类 索引类型|区别 ---|--- 普通索引|简单索引,数据可以为空 主键索引|主键索引。索引列唯一且不能为空;一张表只能有一个主键索引 唯一索引|数据必须是唯一的,但可以为空 联合索引|多个列联合到一起建立的索引,使用时有最左原则需要注意 全文索引|全文搜索的索引。用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。 ## 索引的数据类型 `B+tree`、`hash` ### 为什么没有用`二叉树` #### 二叉树的定义 [二叉树]() 如果选择二叉树做索引的话假如说在主键建立索引,因为索引一般都是主键自增的,那就不会往树的左节点做插入,那索引树就会降级成为单向链表,如下图所示: ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/BinaryTree.gif) 原始二叉树的查找`时间复杂度`是`O(1)`, 降级成为单向链表后的时间复杂度是`O(n)` ### 为什么没有选择`红黑树` 红黑树是一种含有红黑结点并能自平衡的二叉查找树。 虽然它能够自平衡,但是树的高度不可控,假如树高20 那就需要查询20次。也就是20次磁盘IO,如果数据量大的情况下,红黑树也是搞不定的。 ### 为什么没有用`BTree` 在计算机科学中,B树(英语:B-tree)是一种自平衡的树(多叉平衡树),能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。B树,概括来说是一个一般化的二叉查找树(binary search tree)一个节点可以拥有2个以上的子节点。与自平衡二叉查找树不同,B树适用于读写相对大的数据块的存储系统,例如磁盘。B树减少定位记录时所经历的中间过程,从而加快存取速度。B树这种数据结构可以用来描述外部存储。这种数据结构常被应用在数据库和文件系统的实现上。 ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200422122501.png) 节点元素从左到右依次递增排列 子节点所有元素都在父节点区间内 没有选择B树的原因是因为B树的data是跟随每个子节点的而B+tree的的数据和节点是分开存放的数据存放在非叶子节点上 这样数据可以再有限的内存空间里面去维护更多的index ## B+tree B+tree数据格式 ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200422124950.png) ## hash 查询后经过hash运算可以快速获取到某个具体数据的磁盘地址,理论上定向的条件查询效率比较高,但是区间查询就没办法用索引了,所以不推荐hash 每次查找都会把数据load到内存中,从而提高查询效率 ## index创建 ALTER TABLE `table_name` ADD INDEX `index_name` (`column_list`); ```shell script ALTER TABLE user ADD INDEX index_name_city_age (NAME(16),CITY,AGE); ``` 等价于 CREATE UNIQUE INDEX `index_name` ON `table_name` (`column_list`) ```shell script CREATE INDEX user ON user (NAME(16),CITY,AGE) ``` ### 其他创建语句 #### 主键索引 alter table `table_name` add primary key (`columns`); #### 唯一索引 ALTER TABLE `table_name` ADD UNIQUE (`columns`); #### 全文索引 ALTER TABLE `table_name` ADD FULLTEXT (`columns`); ## index删除 ### 普通索引删除 DROP INDEX `index_name` ON `talbe_name` 等价于 ALTER TABLE `table_name` DROP INDEX `index_name` ### 主键索引删除 ALTER TABLE `table_name` DROP `PRIMARY KEY` ## index查看 show index from `table_name`; ## mysql索引命中过程 @todo