mysql 是怎么在磁盘上是存储 NULL 的?

大家知道一般表中char,vachar这些字段都是有值的,那如果某个字段允许为空,且值确实为空,MySql又是怎么处理的呢?

是不是直接存储NULL呢?

假设这个字段的NULL值我们在磁盘上存储的时候,就是按照“NULL”这么个字符串来存储,是不是很浪费存储空间?
因为字符串要占用空间的啊(一个 NULL 字符串要占用四个字符呢),本来他就是个NULL,说明什么值都没有,你还给他存个“NULL”字符串干什么呢?

NULL值列表

NULL值列表,顾名思义,说的就是你一行数据里可能有的字段值是NULL,比如你的某个字段,它是允许为NULL的,那么实际上在存储的时候,如果你没给它赋值,那么这个字段的值就是NULL了。

而我们又知道了 NULL 值是肯定不会直接按照字符串的方式存放在磁盘上浪费空间的,那么它到底是怎么存储的呢?

MySql是如何通过二进制来存储NULL值的?

其实NULL值是以二进制bit位来存储的,Compact 格式数据中的NULL值列表就是用来存储NULL值的。若有某个字段值为 null,将将其 bit 位置为 1 说明值为 NULL,bit为 0 说明该字段值不为空。

比如我们有一张学生表,建表语句如下

CREATE TABLE student (
name VARCHAR(10) NOT NULL,
age CHAR(2),
gender CHAR(1),
class VARCHAR(20),
) ROW_FORMAT=COMPACT;

该表有4个字段,分别为name、age 、gender 、class ,代表学生的姓名,年龄,性别,班级,其中有2个变长字段,2个定长字段,name字段是声明了NOT NULL的,就是不能为NULL,其他字段都可能是NULL的。

那么假设这个表里有如下一行数据:“tom NULL m NULL”,其中两个字段都是NULL,那么他在磁盘上是怎么来存储的呢?

首先看变长字段长度列表,他一共有2个变长字段,并且应该按照逆序的顺序,先放class字段的长度,再放name字段的值长度。但是这里由于class字段没有值,为NULL,所以我们只用放name字段的长度,也就是0x03

接着来看NULL值列表,对于允许为NULL的字段,每个字段都有一个二进制bit位的值,如果bit值是1说明是NULL,如果bit值是0说明不是NULL。

对于上面的表而言,3个字段都允许为NULL,每个字段都会有一个bit位。
而这一行数据的值是"tom NULL m NULL",其中2个字段是NULL,1个字段不是NULL,所以3个bit位应该是:101

但是实际放在NULL值列表的时候,他是按逆序放的,所以在NULL值列表里,放的是:101(这里跟上面看起来没什么不同,这是由于案例的特殊性,大家记住其实它是逆序的就行了)

另外NULL值列表一般起码是8个bit位的倍数,如果不足8个bit位就高位补0,所以实际存放的看起来是这样的:

0x03 00000101 记录头信息 tom m

实际上像"tom" "m"这些字符串不是直接以字符串的形式存在磁盘上的,而是根据我们数据库指定的字符集编码,进行编码之后再存储的。

你可能感兴趣的:(mysql,数据库,mysql)