说的都是Innodb引擎
索引
索引分为聚簇索引和二级索引,一个表只能有一个聚簇索引,为什么?
因为聚簇索引的叶子节点存储的是磁盘真实数据,而磁盘真实数据只能有一份,不然复制多份的话就是浪费空间。
一个表必定有一个聚簇索引,为什么?
因为你的表的数据总要存一个地方吧,存起来总要有个数据结构吧,这个结构就是B+树,即聚簇索引。
对这里有疑问是因为使用图形化界面navicat产生的错觉,以为表中的数据也要这样一行一行地存起来,其实不是的。
聚簇索引需要选择一个唯一标识,这个标识能够区分每一行,表中有主键的话,这个唯一标识就是这个主键,没有主键的话,就会选择一个索引字段,如果既没有主键也没有索引字段,就会使用每一行生成的rowId。
索引B+树是在磁盘还是内存?
索引是在磁盘上的,只不过查询请求会将磁盘上的索引页和数据页存储到内存BufferPool上,下次查询的时候,如果发现BufferPool上有对应的索引页就直接使用该索引页进行查询,如果有数据页就直接找到数据并返回
将数据以数据页的形式读取到内存中时,内存中以什么数据结构存放这些数据页?
反正不是B+树,B+树是在磁盘上的。
如果说索引是在内存中的,那为什么又说聚簇索引的叶子节点是真实数据?
说不通,所以索引确实是在磁盘上的
如果说索引是在磁盘中的,那怎么通过B+树来找出对应的数据在哪?计算不是要在内存中进行吗?
因为会将磁盘中的B+树的节点读到内存中来(如果内存中有对应的节点就直接使用),再进行查找。
之前学到:客户端发来一个查询请求,服务端会先判断内存(BufferPool)中有没有这个请求所对应的数据,有的话直接将内存中的数据返回客户端,没有的话就将磁盘中的数据存在内存中,再返回客户端,疑问的点是服务端是怎么判断内存中有没有这个请求对应的数据的?
B+树的每个叶子节点是一个数据页,而非叶子节点就有多个数据页,但是这些数据页只有页目录,没有具体数据,可以说存的是一个范围,如:根节点存的是(数据页1~10),表示树上只有数据页1~10,然后这个根节点的多个字节点有可能就是(1~3),(4~7),(8~10)。
每个数据页有个属性是存该数据页存的记录中最大的记录和最小的记录,如主键索引,就存的该数据页所存记录中最大的id和最小的id。一个非叶子节点是(4~7),如果数据页4的最小记录是22,数据页7的最大记录是50,那么这个字节点就表示id在22~50的都搜这个节点,然后这个节点又有它的子节点,一直搜索下去,知道搜索到叶子节点,就得到一个精确的数据页,要查的数据就在这个数据页里面,此时再通过页目录来找到记录在哪个槽,最后找到记录返回给客户端
假设现在要查一个id为36的记录,就要先去根节点检查这个id为366的记录应该在哪个子节点,一直重复这个步骤,知道查到叶子节点就查找成功了。