mysql中具体的数据是存储在行中的,而行是存储在页中的。也就是说页是凌驾于行之上的。
mysq一个页大小为16K,当然这个大小是可以通过修改配置文件来改变的。
mysql页结构大致示意图:
当我们新建一个表的时候表中用户记录部分(user records)部分是空的,在我们插入一条记录后会被记录到其中,直到插入满时会把记录信息刷入到下一个页中,循环往复。。。
记录头信息大致示意图:
1.delete_mask:表示该行记录是否被删除其实就是删除记录的标识位并占用一个二进制位,其中0--未删除 1--已删除
2.heap_no:表示当前记录在该页中的位置,除此之外heap_no中还存在两条虚拟记录行用于记录当前页中最大记录和最小记录的主键值
3.next_record:表示当前记录的真实数据到下一条记录的真实数据的地址偏移量,其实这就是个单项链表,可以通过一条记录找到下一条记录。但值得注意的是下一条记录并不是我们插入顺序的下一条记录而是按照主键值由小到大的顺序的下一条记录。而且规定最小记录的下一条记录就是本页中存储的主键值最小的记录,而本页中主键值最大的记录的下一条记录就是本页中的最大记录
如图所示:
上图所示的记录的顺序是顺序插入的记录顺序(1.2.3.4),可是我们在实际开发中经常会出现非顺序插入的情况。如下图所示:
当出现非顺序插入的情况,虽然插入顺序由(1.2.3.4)变为了(1.2.4.3)但是它的链表顺序是不会改变的依旧保持(1.2.3.4)这里需要注意的是图中heap_no的顺序插入和heap_no的非顺序插入是不一样的。
当我们在实际开发过程中出现表记录删除的情况时上图中的相应记录信息也会发生变化例如:最大记录行和最小记录行的变化(可能会变化)、next_record的变化(参照数据结构中单链表删除时的变化,后继指针置空操作)、delete_mask的变化(0--未删除 1--已删除)、heap_no的变化、n_owned值的变化
注意:不论我们怎么做增删改操作,InnoDB对页中的数据始终会维护一个单向链表,链表中各个节点是按照主键值由小到大的顺序来存储的