聚集索引/聚簇索引,叶子节点包含了完整的数据记录,InnoDB的主键索引就是一个聚集索引,他的索引和数据是分开的在两个文件,MYISAM的是非聚集索引,索引和数据是分开存储的。InnoDB的主键索引我们叫做聚集索引。
为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
我们看一下这个问题为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
为甚innoDB表建议要有自增的主键,尽量建主键,建整形自增的?其实很简单,设计如此,mysql设计的就是innoDB把你的数据和主键索引用B+Tree来组织的,没有主键他的数据就没有一个结构来存储。
建innoDB表的时候没有建主键,表也能建成功,为什么?
不建主键不代表没有主键,没有建主键innodb会帮你选一个字段,一个可以标识唯一的字段,选为默认字段,如果这个字段唯一的话,不重复,可一键唯一索引的话,就会作为类似于唯一索引,用这个字段来作为唯一索引来维护整个表的数据。如果没有,mysql会生成一个唯一的列,类似于rowid,只不过你看不到,他会用生成的这个唯一列,维护B+Tree的结构,查数据的时候还是用B+Tree的结构去查找。
为什么推荐整形呢?
我们想象一下查找过程,是把节点load到内存然后在内存里去比较大小,也就是在查找的过程中要不断的去进行数据的比对。假设UUID,既不自增也不是整形。问一下,是整形的1<2比较的效率高还是字符串的“abc”和“abe”比较的效率高呢?显然是前者,因为字符串的比较是转换成ASICI一位一位的比,如果最后一位不一样,比到最后才比较出大小,就比整形比较慢多了,存储空间来说,整形更小。索引越节约资源越好。
为什么是自增的呢?
我们可以看一下B-Tree的叶子节点之间是没有指针的,B+Tree优化后增加了叶子节点之间的指针,如果我们遍历数据,从当前节点遍历完之后,就可以根据节点间的指针快速找到下一个节点去遍历。讲到这,穿插一下B+Tree为什么要比B-Tree多一个节点间指针呢?那就讲一下索引的另一种数据结构就是hash。
HASH索引
99.99的情况都是用B+Tree,也有些情况用hash。假设我们的索引选的是hash的数据结构,每插入一个元素会把我们的索引字段做一次hash计算,把运算的到的结果值和这一行的所在磁盘地址做一个映射。
对索引元素的值做一次hash运算就可以在hash映射表里快速找到这一行的磁盘文件地址,经过一次hash就可以快速定位到索引所在行的磁盘文件地址,hash这么快,表有一亿个数据按这种算法,那也就可能经历一次hash运算就可以快速找到某页任意一行数据元素的所在的磁盘文件地址,那比B+Tree快的多啊!就是快的多,为啥99.99的都是B+Tree不是hash呢?
hash的等值查询比B+Tree快,上亿依然很快,为啥很快却不使用?最主要的原因是什么?因为如果使用范围查找,hash就没有用武之地了,范围查找也是很常用的吧,所以基本就不怎么用hash这种数据结构。那B+Tree就很好的支撑范围查找吗?
是,B+Tree可以很好的支撑。
看一下这个B+Tree的结构
刚才我们说了B+Tree的任一叶子节点内部是从左到右都是递增的,且节点之间有一个指针(双向的,图不标准),