存储,读取
    (1)变长字段在磁盘中如何存储的?
    假设有一行数据 字段类型是 VARCHAR(10),CHAR(1),CHAR(1)
    那么他的行的值 第一行 hello a a 第二行 hi a a ,然后两条数据写入磁盘文件里,两行数据是挨在一起的,一个磁盘文件里可能有下面的两行数据:hello a a hi a a 你看到的表里的很多行数据,最终落地到磁盘的时候,都是一堆数据放在一个磁盘文件里的。

    (2)如何读取?
    引入变长字段的长度列表,解决行数据的读取问题,比如 hello a a 这行数据,hello的长度是5,存储在磁盘文件里类似格式如下 0x05 null值列表,数据头 hello a a,然后上面的两行数据放在一起存储在磁盘文件里,看起来如下:
    0x05 null值列表 数据头 hello a a 0x02 null值列表 数据头 hi a a

    (3)如何解决变长字段的存储问题?
    假设读取 Hello a a 这行数据,你首先会知道表里的三个字段类型是 VARCHAR(10) CHAR(1) CHAR(1) ,此时读取第一个字段的值,那么第一个字段是变长的,到底它的长度是多少?
    然后会发现存储的 变长字段长度 是 5,这样就可以读取了。

    (4)如果多个变长字段,如何存放他们的长度?
    比如一行数据有VARCHAR(10) VARCHAR(5) VARCHAR(20) CHAR(1) CHAR(1),一共5个字段,其中三个是变长字段,
    此时假设一行数据是这样的:hello hi hao a a
    那此时在存储这行数据开头变长字段的长度列表中 存储几个变长字段的 长度,但是注意,变长字段的长度是逆序存储的,值也是逆序放的
    ,即也就是说先存放VARCHAR(20) 这个字段的长度,然后存放 VARCHAR(5)这个字段的长度,最后存放VARCHAR(10)这个字段的长度。 存放时 0x03 0x02 0x05 null 值列表 头字段 hello hi hao a a

    数据紧凑的方式主要是节省磁盘空间,降低碎片率,查询的时候可以和更快速

    为什么不使用序列化的方式存储数据获取数据?
    因为不需要每次都获取全部数据,只获取其中一两个字段的话,按照现在的序列化方式,就可以计算出字段对应的偏移量来获取;java对象的存储其实也是这样的,看unsafe类就知道

    逆序存放的原因?
    NULL 值字段列表和可变长字段列表逆序存放是因为一条数据指向下一条数据的指针(next_record 指针)是记录的真实数据的起始地址,从这个地址开始往后读就是这行数据的真实数据(我们用的字段),从地址往前读就是逆序的 NULL 值字段列表和可变长字段列表,这样可以使得位置靠前的字段和它对应的长度信息或者是否为 NULL 值的信息距离更近,提高缓存的命中率