postgresql - 在 PostgreSQL 中不使用 NULL 是否仍然在 header 中使用 NULL 位图?

标签 postgresql database-design null storage

显然 PostgreSQL 在 header of each database row 中存储了几个值.

如果我不在该表中使用 NULL 值 - 空位图是否仍然存在?
使用 NOT NULL 定义列有什么不同吗?

最佳答案

实际上比这更复杂。

空位图需要行中每列一位,四舍五入到完整字节。只有当实际行包含至少一个 NULL 值并且在这种情况下被完全分配时,它才会存在。 NOT NULL 约束不会直接影响它。 (当然,如果您的表的所有字段都是 NOT NULL,则永远不会有空位图。)

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

./pg_controldata /path/to/my/dbcluster

在典型的基于 Debian 的 Postgres 12 安装上:

sudo /usr/lib/postgresql/12/bin/pg_controldata /var/lib/postgresql/12/main

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

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

这至少对版本 8.4 - 12 有效并且很可能不会改变。

关于postgresql - 在 PostgreSQL 中不使用 NULL 是否仍然在 header 中使用 NULL 位图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5008753/

相关文章:

postgresql - 在事务中开始BinaryImport

database-design - DNA转换域名的最大长度是多少?

mysql - TINYINT 列和 Where 子句中的用法 - 意外行为

kotlin - 如何使用 equals() 和 contains() 检查可为空类型的数据?我想它们都是字符串的方法,但为什么它们的行为不同?

c++ - static_cast 的奇怪用法

oracle - 在 PostgreSQL 上使用扩展名 orafce 安装的模式

postgresql - TimescaleDB/Postgres 占用的空间远超预期

perl - 存储和访问数据以供将来分析运算符(operator)内部和运算符(operator)之间的可变性

c# - ASP.NET MVC 上的大数据库项目

mysql - 使用 TIMESTAMP 数据类型创建单独的表来跟踪特定列