PostgreSQL:BYTEA与OID +大对象?

时间:2011-01-10 08:50:32

标签: java hibernate postgresql blob

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

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

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

所以我想把所有这些都改成bytea。但我担心bytea字段以十六进制编码,因此编码和解码会产生一些开销,这会影响性能。

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

4 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:4)

  

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

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

我没有看到任何基准。

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

tl;dr 除非您需要“流媒体”,否则请使用 bytea。

bytea 是一个字节序列,与任何其他值一样工作。

大对象被分成多行。这允许您查找、读取和写入大对象,例如 OS 文件。您可以对它们进行操作,而无需一次性将整个内容加载到内存中。

但是,大型对象也有缺点:

  1. 每个数据库只有一个大对象表。

  2. 当删除“拥有”记录时,不会自动删除大对象。 (从技术上讲,一个大对象可以被多个记录引用。)请参阅 lo_manage 模块中的 lo 函数。

  3. 由于只有一张表,大对象权限必须逐条处理。

  4. 流式传输很困难,与简单的 bytea 相比,客户端驱动程序的支持较少。

  5. 它是系统架构的一部分,因此您无法控制分区和表空间等选项。

就容量而言,没有太大区别。 bytea 限制为 1GB;大对象限制为 2GB。如果 1GB 太有限,那么 2GB 可能也是如此。

我冒昧地猜测,使用 bytea 会更好地满足 93% 的大型对象的现实用途。