テーブルに次のように定義された列があるとします。
"MyColumn" smallint NULL
0、1などの値を格納するには、2バイト(1)が必要です。しかし、「MyColumn」をNULLに設定した場合、どのくらいのスペースが必要ですか? 0バイトが必要ですか?
管理目的またはすべての列/行にそのようなもののためにいくつかの追加の必要なバイトがありますか?
(1) http://www.postgresql.org/docs/9.0/interactive/datatype-numeric.html
ヌル列は格納されません。行の先頭にはビットマップがあり、列ごとに1ビットがあり、どちらがnullか非nullかを示します。行のすべての列がnullでない場合は、ビットマップを省略できます。したがって、1つ以上のnullがある特定の行の場合、それに追加されるサイズはビットマップのサイズになります(N列テーブルの場合はNビット、切り上げ)。
ドキュメントからのより詳細な議論 ここ
Laramie はビットマップについて正しく、マニュアルの適切な場所にリンクしています。それでも、これはほとんど正しいですが、完全には正しくありません。
したがって、1つ以上のnullがある特定の行の場合、それに追加されるサイズはビットマップのサイズになります(N列テーブルの場合はNビット、切り上げ)。
データアライメントを考慮に入れる必要があります。 HeapTupleHeader
(行ごと)の長さは23バイトで、実際の列データは常にMAXALIGN
の倍数(通常は8バイト)で始まります。これにより、nullビットマップで使用できる1バイトのパディングが残ります。事実上NULLストレージは、最大8列のテーブルに対して完全に無料です。
その後、次のMAXALIGN * 8
(通常は64)列に別のMAXALIGN
(通常は8)バイトが割り当てられます。など常にユーザー列の総数(すべてまたは何も)。ただし、行に少なくとも1つの実際のNULL値がある場合に限ります。
私はそのすべてを検証するために広範なテストを実行しました。詳細:
1バイト(0x00)が必要ですが、スペースの大部分を占めるのはテーブルの構造です。この1つの値を追加すると、データの合計よりも多くのスペースを必要とする何かが変わる可能性があります(行の追加など)。
編集:ララミーは私よりもnullについてもっと知っているようです:)