在PostgreSQL中不使用NULL仍然在标题中使用NULL位图?

Xeo*_*oss 13 postgresql null storage database-design

显然,PostgreSQL在每个数据库行标题中存储了几个值.

如果我不在该表中使用NULL值 - 是否仍然存在空位图?
定义列有NOT NULL没有区别?

Erw*_*ter 26

它实际上比那更复杂.

空位图在行中每列需要一位,向上舍入为完整字节.仅当实际行包括至少一个NULL值并且在该情况下完全分配时才存在.NOT NULL约束不直接影响那个.(当然,如果表的所有字段都是NOT NULL,则永远不会有空位图.)

"堆元组头"(每行)长度为23个字节.实际数据以MAXALIGN此后的倍数开始,在64位操作系统上通常为8个字节(32位操作系统上为4个字节).以root身份从PostgreSQL二进制目录运行以下命令以获得明确的答案:

./pg_controldata /path/to/my/dbcluster
Run Code Online (Sandbox Code Playgroud)

在Postgres 9.3的典型Debian安装上,它将是:

sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,在头部和数据的对齐开始之间存在一个空闲字节,空位图可以使用该字节.只要您的表有8列或更少,NULL存储实际上是完全免费的(就磁盘空间而言).

之后,MAXALIGN为空位图(加填充)分配另一个(通常为8个字节)以覆盖另一个(通常)64个字段.等等.

这适用于至少版本8.4 - 9.6,并且很可能不会更改.

  • @DavidTan:视情况而定。如果行中至少有一个 NULL 值,则仅*每行*分配空位图。在最坏的情况下,这可能意味着第 9 列的整个表重写。 (2认同)