我使用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
字段以十六进制编码,因此编码和解码会产生一些开销,这会影响性能。
关于这两者的表现是否有良好的基准? 有人做过转换并看到了不同之处吗?
答案 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 文件。您可以对它们进行操作,而无需一次性将整个内容加载到内存中。
但是,大型对象也有缺点:
每个数据库只有一个大对象表。
当删除“拥有”记录时,不会自动删除大对象。 (从技术上讲,一个大对象可以被多个记录引用。)请参阅 lo_manage
模块中的 lo
函数。
由于只有一张表,大对象权限必须逐条处理。
流式传输很困难,与简单的 bytea
相比,客户端驱动程序的支持较少。
它是系统架构的一部分,因此您无法控制分区和表空间等选项。
就容量而言,没有太大区别。 bytea
限制为 1GB;大对象限制为 2GB。如果 1GB 太有限,那么 2GB 可能也是如此。
我冒昧地猜测,使用 bytea
会更好地满足 93% 的大型对象的现实用途。