Mysql如何存储一条数据

·  阅读 286

在mysql内存组件bufferPool中我们分析了数据修改、查询的时候是如果进行的,为什么mysql要设计一个bufferPool。为什么不直接在磁盘上操作数据? 其实技术上是可以的,这样做会对磁盘进行随机读写必然导致性能极差,稍微并发高一些就没办法提供服务了。

初识Mysql物理存储格式

我们在创建表的时候可以指定一个行存储格式,也可以在创建表完成后进行修改,这里用COMPACT格式来说。

CREATE TABLE table_name (columns) ROW_FORMAT=COMPACT
ALTER TABLE table_name ROW_FORMAT=COMPACT

在COMPACT格式下大致一行数据存储如下:

变长字段的长度列表、null值列表、数据头、column01、column02、column03、columnN...

对于每一行数据来说都会有个头数据对这行数据进行描述,这个就是行格式COMPACT 只是其中一种其他的行格式也大同小异。

变长字段如何存储

大家知道在mysql中有varchar(50) 这样的变长字段。假设我们一行数据字段为 varchar(50) char(1) char(1) 那是不是 可以存储 (hello v v )、(hi v v) 那现在我们把这两条记录写入磁盘就是 (hello v v hi v v)这个样子我们怎么读取。所以变长字段我们存储的时候是要知道它到底多长的!我可以看到hello长度为5 在16进制就是0x05、hi就是0x02 看起来如下所示:

0x05 null值列表 数据头 hello v v 0x02 null值列表 数据头 hi v v

现在我们需要读取的时候我们肯定知道这个行数据是 varchar(50) char(1) char(1) 那读取的时候变长字段到底多长 现在0x05 你知道了读取五个字符 然后读取 char(1)和char(1),如果有多个变长字段 如: varchar(50) varchar(50) char(1) char(1) hello world a a

0x05 0x05 null值列表 数据头 hello world a a 

null值字段如何存储

我们接着来看看null值字段如果存储,假设我们有一个表

create table Users(
name varchar(50) not null,
address varchar(50),
gender char(1),
job varchar(20),
school varchar(30)
)ROW_FORMAT=COMPACT ;

如上表里面有4个字段可以为null,name 设定为not null 那它在存储的时候假设数据是:(jack、NULL、男、NULL、abcde)

0x05 0x04 00000101 头信息 column01=value1 column02=value2 column03=value3 column04=value4 column05=value2

这个时候去读取的时候就知道可变长字段读取多少个字符,定长字段按照长度读取,null字段判断是否为空就可以完美的读取出数据。这里存储null值字段应该是1010 一般不满8个bit补足8个 所以看起来就是00001010了。

行溢出

最后我们说一下行溢出,我们在前面说过一个数据页就16K 如果一行数据里的某个字段的值能多大于了16k一个数据页装不下。那怎么办?具体点就是有一个字段 为VARCHAR(560000) 这个时候会在那一个数据页存储一部分数据在那个字段中有个20字节的指针指向下一个数据页。反正一个数据页放不下一个字段的时候就会存储到其他的数据页里。

分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改