显然,PostgreSQL在每个数据库行的头部中存储一些值。
如果我在该表中不使用NULL值- 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
无论哪种方式,标头和数据对齐的起始位置之间有一个空闲字节,可供空值位图利用。只要您的表具有8列或更少,则 NULL 存储在磁盘空间方面实际上是完全免费的。
之后,另外MAXALIGN
(通常为8字节)将被分配给空值位图,以覆盖另外(通常)64个字段,依此类推。
这适用于至少版本8.4-12,并且最有可能不会更改。
http://www.postgresql.org/docs/9.0/static/storage-page-layout.html#HEAPTUPLEHEADERDATA-TABLE
每8列需要使用一字节额外的存储空间。那么,对于大约每一百万行,这将占用一兆字节的存储空间。似乎并不是很重要。我会根据需要定义表格,而不担心空标题。
WHERE txt IS NULL
比WHERE txt=''
更快。请参考 https://stackoverflow.com/a/32081389/287948 的正确性(?)。 - Peter Krauss