使用postgresql DB存储NULL值需要多少磁盘空间?

Chr*_*ris 40 sql postgresql types nullable

假设我的表上有一列定义了以下内容:

"MyColumn" smallint NULL
Run Code Online (Sandbox Code Playgroud)

存储类似0,1或其他值的值应该需要2个字节(1).但是如果我将"MyColumn"设置为NULL,需要多少空间?它需要0个字节吗?

是否有一些额外需要的字节用于管理目的或每个列/行的此类事项?

(1)http://www.postgresql.org/docs/9.0/interactive/datatype-numeric.html

Erw*_*ter 54

Laramie对位图是正确的,他链接到手册中的正确位置.然而,这几乎是,但不完全正确:

因此,对于具有一个或多个空值的任何给定行,添加到其中的大小将是位图的大小(N列表的N位,向上舍入).

人们必须考虑数据对齐.的HeapTupleHeader(每行)是长23个字节,实际列数据总是开始于的倍数MAXALIGN(通常为8个字节).这留下了一个填充字节,可以由空位图使用.实际上,对于最多8列的表,NULL存储是完全免费的.

之后,MAXALIGN为下一个MAXALIGN * 8(通常为64个)列分配另一个(通常为8个)字节.等等.总是用于用户列的总数(全部或全部).但仅当行中至少有一个实际的NULL值时.

我进行了大量测试以验证所有这些.更多细节:

  • 将没有默认值的列添加到大型表通常是一种快速操作.当你越过8到9列之间的阈值(或者`MAXALIGN = 8`时为72和73)时,它会变慢吗? (4认同)
  • @ PatrickBrinich-Langlois:是的,这可能是该机制的结果.在这些情况下,物理表的大小也会超​​出预期.效果不一定是线性的,因为涉及死元组等其他因素.如果现有的NULL位图(每行)具有另一个NULL位的空间,则该表根本不会增长,这是常见情况. (2认同)

Lar*_*mie 47

不存储空列.该行在开始处有一个位图,每列有一位,表示哪些是空或非空.如果所有列在一行中都是非空的,则可以省略位图.因此,对于具有一个或多个空值的任何给定行,添加到其中的大小将是位图的大小(N列表的N位,向上舍入).

来自这里的文档的更深入的讨论