我有一个包含7列的表,其中5列将为空.我将在inttextdatebooleanmoney个数据类型上有一个空列.此表将包含数百万行,其中包含许多空值.我担心空值会占用空间.

另外,你知道Postgres是否索引空值吗?我想防止它索引空值.

推荐答案

基本上,NULL个值在空位图中占据1 bit.但事情没那么简单.

只有当行中至少有一列包含NULL值时,才会分配null bitmap(每行).在包含9列或更多列的表中,这可能会导致一种看似矛盾的效果:将前NULL个值指定给一列可能比向其写入值占用更多磁盘空间.相反,从行中删除最后一个空值也会删除空位图.

从物理上讲,初始空位图在HeapTupleHeader(23字节)和实际列数据或第OID行(如果您仍应使用该行)之间占据1 byte,这alwaysMAXALIGN(通常为8 bytes)的倍数开始.这会留下1 byte个填充空间,供初始空位图使用.

In effect, NULL storage is absolutely free for tables of 8 columns or less (including dropped, but not yet purged columns).
After that, another MAXALIGN bytes (typically 8) are allocated for the next MAXALIGN * 8 columns (typically 64). Etc.

更多详情请参见以下相关问题:

一旦了解了数据类型的对齐填充,就可以进一步优化存储:

但这种情况很少见,可以节省大量空间.通常情况下,这不值得付出努力.

@Daniel已经涵盖了对索引大小的影响.

Note表示dropped columns(尽管现在不可见)将保留在系统目录中,直到重新创建表.这些僵尸可以强制分配(放大的)空位图.见:

Postgresql相关问答推荐

当通过PostgreSQL FDW中的视图使用时,年龄函数的计算方式不同

使用多个分隔符拆分SQL

如何获取实例化视图的列级权限?

我可以将jsonb_set与来自SELECT语句的新值(第三个参数)一起使用吗?

ST_Intersects 太慢

如何判断上次在 TimescaleDB 上运行连续聚合作业(job)的时间

EF Core添加迁移目标postgreeSQL返回无法加载类型'Microsoft.EntityFrameworkCore.Storage.IRelationalValueBufferFactoryFactory

使用 Heroku CLI、Postgres 的 SQL 语法错误

PostgreSQL:根据排序顺序仅 Select 每个 id 的第一条记录

如何在构建时链接 docker 容器?

SQLAlchemy 和多个进程的连接问题

错误:CASE types character varying and numeric cannot be matched

如何使用 psql 命令列出、创建、使用和判断数据库?

pg_restore 会覆盖现有的表吗?

Android 的 JDBC 与 Web 服务

PL/pgSQL 执行与执行

在布尔字段上添加索引

psql 将默认 statement_timeout 设置为 postgres 中的用户

PostgreSQL regexp_replace() 只保留一个空格

PostgreSQL 中具有多个连接的 UPDATE 语句