这一章主要是B+树的基础知识。
6.1查找大体可以分成两个小步骤
定位到记录所在的页 从所在的页内查找相应的记录
InnoDB引擎下,当我们用主键所在的列进行查找时,可以利用页里的Page Directory区中的槽和记录本身的顺序进行快速的查找。
而使用无索引的列时,我们就只能顺序地进行扫描了。这是因为我们不能快速地定位记录所在的页。
这一节在我看来写的有点过长了,其实就是想引出目录项的概念(也就是B+树的内部叶节点)
首先我们要保证每个数据页内部的各个记录是有序的。
接着,我们需要利用目录项,来快速地查找记录所在的页。每个目录项最少要包含主键的值以及对应的页号。其中主键值是每个页面里最小的主键值。
之后,我们可以把目录项这个概念抽象一下:目录项就是只有两列的普通记录。仔细想一下,目录项只需要主键和页号就行了,其实和普通的页没什么区别。
事实上InnoDB中也是这么做的。我们的记录头信息中有record_type属性,当属性值为1时,这个记录就是目录项。
而因为目录项和普通记录并无太大区别,因此可以复用INDEX这种页结构。也就有着同样的PageDirectory区域,方便我们快速地对目录项进行查找。
聚簇索引
1 使用主键值来保证记录和页有序的索引。这句话意味着页内记录、页、目录项都要保证有序。
2 B+树的叶子节点存储的是完整的用户记录。二级索引/辅助索引
指的是对非主键所在列建立的索引结构。
二级索引不保存完整的记录,只保存列值和主键值。因此在二级索引上进行查找大概率需要“回表”(也就是拿着主键值去主索引里再查一次)。
二级索引在技术上也可以保存完整的记录,可这样维护索引的开销就太大了。联合索引/复合索引/多列索引
由多个列一起建立的索引。比较顺序就是从左往右(最左前缀)。
InnoDB B+树索引注意事项
根页面不动
这里指的是页号不动。最开始根页面存的是记录,后来会变成存目录项。后续引擎需要用索引时,只需要查找数据字典就能知道索引对应的根页面页号是多少。
内部叶节点的目录项有唯一性
如果不满足唯一性,会导致无法二分。但是非主键本身可能是允许空值、重复值的,这怎么解决呢?
答案是二级索引会隐式地将主键值添加到索引中保证唯一性。比较时先按索引列比,索引列相同则按主键比。
即使添加唯一性约束,也会因为允许null值和MVCC机制的原因,不得已地将主键值添加到索引中。
一个页面最少容纳两条记录
如果一个页面只存放一条记录,则有可能退化成链表。这样查找效率太低了,因此要求一个页最少容纳两条记录。
MyISAM里的聚簇索引的叶子节点不存放完整的记录,而是存放一个行号。这是因为MyISAM引擎的索引和数据文件是分开存储的。
一个表里的数据只会在一个数据文件中。因此通过行号可以唯一定位一条记录。
当然,这是针对定长记录的。如果是不定长记录,则需要在索引的叶子节点里维护一个页内偏移量。(这里别担心只维护偏移量不知道记录多长,记录的长度会记录在记录头信息中。)
CREATE TABLE 表名 ( 各个列 (KEY | INDEX) 索引名 (索引列1, 索引列2...) ); ALTER TABLE 表名 ADD (INDEX|KEY) 索引名 (索引列) ALTER TABLE 表名 DROP (INDEX|KEY) 索引名
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)