问题 PostgreSQL:BYTEA与OID +大对象?


我用Hibernate 3.2和PostgreSQL 8.4开始了一个应用程序。我有一些 byte[] 映射为的字段 @Basic (= PG bytea)和其他被映射为的 @Lob (= PG大对象)。为什么不一致?因为我是一个Hibernate菜鸟。

现在,这些字段最大为4 Kb(但平均为2-3 kb)。 PostgreSQL文档提到,当字段很大时,LO很好,但我没有看到“大”意味着什么。

我已经使用Hibernate 3.6升级到PostgreSQL 9.0,我不得不将注释更改为 @Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")。这个错误带来了潜在的兼容性问题,我最终发现,与普通字段相比,Large Objects是一个很难处理的问题。

所以我想把它全部改成 bytea。但我担心的是 bytea 字段以十六进制编码,因此在编码和解码时会有一些开销,这会损害性能。

关于这两者的表现是否有良好的基准? 有人做过切换并看到了不同之处吗?


2493
2018-01-10 08:50


起源



答案:


基本上有些情况下每个都有意义。 bytea更简单,通常更受欢迎。客户端库为您提供解码,这不是问题。

但是LOB具有一些简洁的功能,例如能够在其中进行搜索并将LOB视为字节流而不是字节数组。

“大”意味着“足够大,你不想一次性将它发送给客户。”从技术上讲,bytea被限制为1GB压缩,并且高压限制为2GB压缩,但实际上你首先达到了另一个限制。如果它足够大,你不希望它直接在你的结果集中,并且你不想一次性将它发送到客户端,使用LOB。


5
2017-09-05 09:17





但我担心bytea字段   以十六进制编码

bytea输入可以是十六进制或转义格式,这是您的选择。存储将是相同的。从版本9.0开始,输出默认值为十六进制,但您可以通过编辑参数来更改此值 bytea_output

我还没有看到任何基准。


4
2018-01-10 09:07



它也没有存储为十六进制,我认为libpq(甚至可能是协议)都有一个二进制传输接口。 - Chris Travers


答案:


基本上有些情况下每个都有意义。 bytea更简单,通常更受欢迎。客户端库为您提供解码,这不是问题。

但是LOB具有一些简洁的功能,例如能够在其中进行搜索并将LOB视为字节流而不是字节数组。

“大”意味着“足够大,你不想一次性将它发送给客户。”从技术上讲,bytea被限制为1GB压缩,并且高压限制为2GB压缩,但实际上你首先达到了另一个限制。如果它足够大,你不希望它直接在你的结果集中,并且你不想一次性将它发送到客户端,使用LOB。


5
2017-09-05 09:17





但我担心bytea字段   以十六进制编码

bytea输入可以是十六进制或转义格式,这是您的选择。存储将是相同的。从版本9.0开始,输出默认值为十六进制,但您可以通过编辑参数来更改此值 bytea_output

我还没有看到任何基准。


4
2018-01-10 09:07



它也没有存储为十六进制,我认为libpq(甚至可能是协议)都有一个二进制传输接口。 - Chris Travers


我没有比较大对象和bytea方便,但请注意,在9.0中切换到十六进制输出格式也是因为它比以前的自定义编码更快。就二进制数据的文本编码而言,你可能不会比现在快得多。

如果这对您来说不够好,您可以考虑使用PostgreSQL客户端和服务器之间的二进制协议。然后你基本上直接从磁盘上获取东西,就像大对象一样。我不知道PostgreSQL JDBC是否支持它,但快速搜索表明没有。


1
2018-01-10 13:56