问题描述
为了在 Postgresql 中处理 bytea 值,我通常会序列化到十六进制并从十六进制反序列化。这似乎是首选方式。但是,Postgresql 服务器上实际存储的是什么?它是十六进制还是未十六进制的二进制文件?我关心的原因是十六进制显然会占用两倍于未十六进制二进制的空间。当我说 unhexed binary 时,我的意思是十六进制字符串“00”,它是 2 个字节,只是“0”,它是 1 个字节,作为非十六进制二进制。
上下文是我有一个 Postgres 数据库和一个 Scylla 数据库,它们以几乎完全相同的格式存储完全相同的数据。但是,Postgres 使用的总空间几乎是 Scylla 使用空间的两倍。对于 Scylla,我不会将二进制编码为十六进制。我只是通过网络发送原始二进制文件。我不希望这两个数据库使用完全相同的空间量。但是对于 Postgresql 使用 double 空间是相当多的开销,而且几乎精确的加倍确实让我怀疑数据是以十六进制而不是实际二进制存储在服务器上的(因为十六进制使用的空间正好是实际二进制的两倍)。
解决方法
bytea
以二进制形式存储,而不是十六进制编码,这将是非常浪费的。十六进制表示只是类型输出函数生成的默认文本表示。
我不知道 Scylla,所以我无法解释其中的区别,但是 PostgreSQL 每行(23 字节)有大量开销,并且每 8kB 块也有一些开销。
您在评论中说您测量了数据库大小,其中包括所有元数据和索引。我建议你用pg_table_size
来测量表格。
请注意,如果表行超过 2000 字节,PostgreSQL 会自动压缩值。