问题
- 如何理解mysql中 数据存放在`B+树`的叶子节点而不是其他非叶子节点?
- (InnoDB中)B+树的叶子节点一定存放全部的真实数据吗?辅助索引和聚集索引的B+树有什么区别?联合索引的B+树中数据又有啥区别呢?
- MyISAM中的索引是什么样的?
解答问题一
快速理解
你可以把mysql中存放的数据比作一本书的目录,然后这个目录中有大标题,小标题,大目录,小目录,目录的最下面就是具体文章的页数(InnoDB中最下面就是真实的数据)。
详解
首先B+树的叶子节点我们已经知道了存放的是真实数据,那么其他节点呢?叶子节点的父节点存放的是什么?最简单的回答就是:存放的是目录 ,这个目录有点特殊,首先举例来说:假如有三层树,最底层就是存放的数据,第二层存放的是这条数据的 页号和最小主键值,这个组合就是一条新的数据,称为目录项记录,很多条这种数据记录着底层数据的主键和页号信息,查找的时候可以通过最先通过记录目录项数据页定位真实数据存放在哪个数据页(InnoDB最小单位按页来的,大小16KB),那第一层呢?第一层和第二层一样,同样存放的是第二层目录项记录的页号和该页下面的最小主键值,即数据页中记录的类型都一样,但是主键范围更广了。
总结补充
用户记录和目录项记录存放的地方都是一样的,都在基本单元数据页里面,但是记录类型有差别的,在每条记录的头信息中有个叫record_type字段,每一种代表不同的类型
sql 0:普通的用户记录 1:目录项记录 2:最小记录 3:最大记录 用上面这种储存结构,熟悉二分法的我们很清楚,数据从小到大排列,每页跨度逐渐减小,这不就是二分法的优势吗?快速定位某一页,再从页定位到真实记录,这就是强大之处。
问题二解答
B+树中叶子节点存放的真实数据没错,但是每一棵树并不是存放的是全部真实数据,这里就牵扯到了聚集索引和辅助索引,聚集索引不需要人为的去主动创建,你可以把上面提到的数据真实存放目录当作聚集索引,一开始的时候就安排好了,数据就是按照这个目录存放的。
辅助索引就不一样了,我们随机选取了某一列作为索引,那么InnoDB会新创建一棵B+树,数据存放的格式和前面提到的一样,只不过排序的不是主键,而是你选取的这一页,底层叶子节点中你选取的列+主键,当你使用这个索引的时候首先查询到的是这个数据的主键,然后再去回表检索完整数据,需要注意的是,因为这些列的值可能是相同的,所以目录项记录的时候无法区分,所以和聚集索引有区别的是,辅助索引的目录项记录不仅包含页号和列值,还有一个主键值。
联合索引中B+树叶子节点中数据排序方式就是按照你创建索引的那几个列来的,第一列相同,则按照第二列,依次向后比对。而叶子节点的数据则包含你创建索引的几个列和主键值,同样检索其他列数据需要回表操作。
问题三解答
首先要明确的是,MyISAM中数据和索引是分离的,数据是数据,索引是索引分开储存,通过索引行号定位数据的地址偏移量,然后回表迅速定位数据。所以如果要按照聚集索引的标准来说,那么MyISAM创建的索引均属于二级索引。