此文为观看黑马程序员课程的一些理解和笔记
一、索引的分类
在InnoDB中根据索引的存储形式,又可分为以下几种:
- 聚集索引:将数据存储与索引放到一块,索引结构的叶子结点保存了行数据,聚集索引有且仅有一个(即使你在建表时不显式指定创建聚集索引,系统也会在底层帮你创建)
- 二级索引:将数据与索引分开存储,索引结构的叶子结点关联的是用于聚集索引的列值(大部分情况下,该关联值为主键,因为聚集索引默认为使用主键创建
二、聚集索引选取规则
- 如果存在主键,主键索引就是聚集索引。
- 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
- 如果表没有主键,且没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。
理解:如上图,聚集索引的叶子结点存储的row即数据本身,在创建表时聚集索引随之生成,从上图可知,索引项的排序方式和表中数据记录排序方式一致,因为左边的表是聚集索引中的数据的一种表示方法,数据和聚集索引是关联在一起的,相互依存的,存储在一起的。当你为表中的其他列建立了索引时,该索引为二级索引,即索引的叶子结点只保存了主键值(上图的聚集索引是根据主键建立的),相当于保存了数据的引用(这一点与聚集索引不同,聚集索引保存数据本身,对数据的增删查改都是在对聚集索引中的数据做操作),所以在根据二级索引做查找时,先在二级索引中查找出主键值,再根据主键值在聚集索引中查找数据本身。这也是它为什么叫二级索引的原因(需要查找两次)。
eg:
select * from tablename where id = 28 执行的操作是直接在聚集索引中查找(根据B+树的性质查找,时间复杂度为O(log n))28所对应的row数据,查询效率高。
select * from tablename where name = len 执行的操作是先在二级索引中查找(根据B+树的性质查找,时间复杂度为O(log n))到 len 对应的主键为28,再到聚集索引中根据主键28查找到叶子结点中对应的row数据,查询效率较高。
若where中的条件是对没有建立索引的列进行的查找,则我猜测是在聚集索引的叶子结点中进行链表遍历来查找(根据链表性质进行查找,时间复杂度为O(n)),因为B+树的相邻叶子结点中通过指针相连,可以进行从头到尾的链表遍历,但这种查询的查询效率不高。
ps:为什么在上文中我会反复提及到聚集索引的叶子结点中存的就是数据本身呢?因为在一开始的时候我一直以为聚集索引中将数据存储与索引放到一块的意思是数据放一堆然后聚集索引紧挨着数据存储且叶子结点中存的是数据的引用。因为一开始学索引的时候经常听到老师说索引中存放的是数据的引用。后来反复的读数据索引的定义才领悟原来聚集索引与数据是共存的。
写在最后:以上仅为我自己在听课时的一些感悟,若有错误,还请大家指正。