Laramie is right about the bitmap, and he refers to the right place in the manual. However, this is almost, but not entirely correct:
So, for any given row with one or more zeros, the size of the bitbip added to it will be a bitbip (N bits for the table of N-columns, rounded up).
It is necessary to consider data alignment. HeapTupleHeader (for each row) has a length of 23 bytes, the actual column data always starts with a multiple of MAXALIGN (usually 8 bytes). This leaves one fill byte, which can be used by a null bitmap. In fact, NULL storage is completely free for tables with up to 8 columns .
After that, other MAXALIGN (usually 8) bytes are allocated for the next columns of MAXALIGN * 8 (usually 64). Etc. Always for the total number of user columns (all or nothing). But only if the string has at least one actual NULL value.
I conducted extensive tests to verify all of this. More details:
- Doesnβt NULL in PostgreSQL still use a NULL bitmap in the header?
Erwin Brandstetter 04 Oct 2018-11-11T00: 00Z
source share