在 MySQL 的存储机制中,关于 NULL
值是否占用 1 bit 的存储空间,存在一个常见的理解误区。许多人认为“每个 NULL
值占用 1 bit”,但这并不完全准确。本文将通过 InnoDB 引擎的存储原理,详细解释 NULL
值的实际存储开销,并澄清这一误解。
一、核心结论
- 允许为
NULL
的列会引入位掩码(Bitmask) ,但 位掩码的开销是按字节分配,而非按单个NULL
值分配。 NULL
值本身不存储数据内容,但通过位掩码标记是否为NULL
。- 固定长度类型(如
INT
)的NULL
值不占用数据空间,仅通过位掩码标记。 - 可变长度类型(如
VARCHAR
)的NULL
值同样不占用数据空间,但比空字符串(''
)节省 1-2 字节的长度信息。
二、位掩码机制详解
1. 位掩码的作用
InnoDB 的每行数据开头有一个 NULL 位掩码,用于标记哪些允许为 NULL
的列实际存储了 NULL
值。
- 每个允许为
NULL
的列在位掩码中对应 1 bit。 - 位掩码的总大小按字节向上取整:
位掩码字节数 = ⌈允许为 NULL 的列数 / 8⌉
。
示例:
- 若表中有 5 个允许为
NULL
的列,位掩码占用 1 字节(5/8=0.625 → 向上取整为1)。 - 若有 9 个允许为
NULL
的列,位掩码占用 2 字节。