innodb是怎样逐步插入一条数据的(二)

开课吧开课吧锤锤2021-03-05 09:45

    Java编程语言是一种简单、面向对象、分布式、解释型、健壮安全、与系统无关、可移植、高性能、多线程和动态的语言。如今Java已经广泛应用于各个领域的编程开发。

Java

    区/簇/Extent

    由于一卷原始的纸太过于庞大,展开后可能会铺满我豪宅地板十几层,甚至几十层,非常不方便使用,毕竟我9平米的豪宅还需要留出空间会客。最好的办法就是把这些纸张切割成一张张A4大小的数据页。

    同理,一个磁盘或文件的容量也是非常可观,极其不便管理,因此innodb把文件划分成一个个大小相等的存储块,这些块也被称为页;

java

    对于一部文学故事而言,只要通过页码就可以依次找到下一页,从而完整的读完这个故事。通常我们读完第一页时,会马上接着读第二页,但此时对应的书页如果零散的分布在卧室、厕所、客厅,将使阅读体验大大折扣。如果能把这些分散的书页合订成本,就可以极大地提高阅读的便利性。

    根据局部性原理,cpu在使用的数据时,下一步也会大概率使用逻辑上相邻的数据。因此为了提高数据读操作的性能,innodb把逻辑上相临的数据尽可能在物理上也存储在相邻的页中;为了实现这一目标,Innodb引入了区/簇的概念;

Java

    一个区/簇是物理上连续分配的一段空间,extent又被划分成连续的页,以存储同一逻辑单元的数据(如下面的索引段、数据段)。一个区/簇,默认由64个连续的页(Page)组成,每个页默认大小为16K。

    实际上,innodb是先把文件划分成连续的区/簇,然后在区/簇内再划分出连续的页,从总体上看:一个文件即是微观上一系列连续的页组成,也是宏观上一系列连续的区/簇组成。知道一个页的页号和页大小就可以计算出此页在磁盘上的具体位置,同理知道一个页号就可以计算出一个区/簇的大小以及页所在的区/簇是第几个区/簇(它本身没有编号,但假设第一个区/簇为0号,可以知道它逻辑上是第几个)。

    如果把页看作现实书本中的页,那么extent可以看作现实中的书本。

    区的目的是为逻辑单元分配连续的空间,同时也用于管理区内的存储空间状态(如:区内哪些页已满,哪些还未使用,哪些包含碎片)。具体通过不同的区/簇链表来指明区本身的空间状态,以及通过XDESEntry中的XDES_BITMAP指明区内页的空间状态)。

    ###段/Segment

    当年大刘写完三体第一本后,迟迟没有更新,但由于内容过于精彩,导致奥巴马又是写邮件,又是通过外交手段催更。为了避免中美关系受损,大刘如法炮制,又连续写了两本。

    在逻辑上故事情连贯的这三本书总体上都叫三体,于是我们称这种具有相关性的多本书为一套。同理,innodb把逻辑上有关联的区/簇归属为一个段。

Java

    为了使同一逻辑单元可以在物理上具有连续的存储空间,Innodb提出的区的概念,但是io的最小操作单元为页,一次io并不能写满一个区,同时数据是可以擦除(删除)重写,因此必须记录区自身以及区内的空间状态:哪些区已写满,哪些区还未使用,哪些区还有碎片空间。

    innodb中把这些记录具有相关性区的存储空间状态的管理信息称为段实体,段实体所管理的区的总和称为段。段的目的是管理区的使用情况以及为数据分配空间时,提供空间存储状态。

    段可以类似的看做现实中一套书中的套。

    innodb中数据是以B+树的方式组织,叶子节点存储关键字与行数据,非叶子节点存储关键字(索引数据)与页号。索引数据与业务行数据分别具有不同的数据结构,因此它们被分开存储,非叶子节点的索引数据存储在一个段中,叶子节点的业务数据存储在另一个段,对应的它们也分别存储在不同结构的区和页中。

    数据逻辑结构如下:

Java

    物理存储结构如下:

Java

    段是表空间的逻辑组成部分,用来存储具有相同意义的数据,如:B+对中的非叶子节点或B+树中的叶子节点。常见的段有数据段、索引段、回滚段等。

    每创建一个索引就会创建两个段:一个是数据段(B+树对应的叶子节点),一个是索引段(非叶子节点)。对于聚集索引(一般是主键索引)数据段存储的是索引关键字和业务行(所有字段);对于非聚集索引,数据段存储的是索引关键字和主键;如果通过非聚集索引查询,需要先通过B+树查出主键,再通过主键从聚集索引中二次查询具体的行,这称为回表。

    下图:左边为二级索引(非聚集索引),右边为主键索引(聚集索引)

Java

    表数据是通过聚集索引组织存储,也即按主键索引创建的B+树存储数据,因此创建表时应该同时指定一个主键。如果没有指定主键,也没有创建唯一索引,表会默认创建一个自增的隐藏字段:row_id做为聚集索引B+树的关键字段。因为是隐藏字段,所以这个字段只能回表查询时使用。

    以上内容由开课吧老师敖丙提供,更多Java教程尽在开课吧广场Java教程频道。

有用
分享