java PostgreSQL:BYTEA vs OID+Large Object?

yiytaume  于 2023-05-15  发布在  Java
关注(0)|答案(4)|浏览(144)

我用Hibernate 3.2和PostgreSQL 8.4启动了一个应用程序。我有一些byte[]字段被Map为@Basic(= PG bytea),其他字段被Map为@Lob(=PG Large Object)。为什么不一致?因为我是个 hibernate 菜鸟。
现在,这些字段最大为4 Kb(但平均值为2-3 kb)。PostgreSQL文档提到,当字段很大时,LO是好的,但我不明白“大”是什么意思。
我已经升级到PostgreSQL 9.0与Hibernate 3.6,我坚持改变注解为@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")。这个bug带来了一个潜在的兼容性问题,我最终发现,与普通字段相比,处理大型对象是一件痛苦的事情。
所以我想把它全部改成bytea。但是我担心bytea字段是用十六进制编码的,所以在编码和解码时会有一些开销,这会影响性能。
是否有关于这两种性能的良好基准?有没有人做了转换,看到了不同?

btxsgosb

btxsgosb1#

基本上,每种情况都有意义。Bytea更简单并且通常是优选的。客户端库给予你解码,所以这不是一个问题。
然而,LOB有一些简洁的特性,比如能够在其中进行查找,并将LOB视为字节流而不是字节数组。
“大”的意思是“大到你不想一次发送给客户端。”从技术上讲,bytea被限制为1GB压缩,而一个lob被限制为2GB压缩,但实际上你首先要达到另一个限制。如果它足够大,你就不想它直接出现在结果集中,你也不想;如果您不想一次将其全部发送到客户端,请使用LOB。

ny6fqffe

ny6fqffe2#

但我担心字节字段是用十六进制编码的
bytea输入可以是十六进制或转义格式,这是你的选择。存储将是相同的。从9.0版开始,输出默认值是十六进制,但是您可以通过编辑参数bytea_output来更改它。
我没有看到任何基准。

xdnvmnnf

xdnvmnnf3#

tl;dr使用字节茶

...除非您需要流式传输或>1GB的值

**Bytea:**一个字节序列,其工作方式与任何其他TOAST值相同。每个值限制为1GB,每个表限制为32 TB。
**大对象:**二进制数据拆分成多行。像操作系统文件一样支持查找、读取和写入,因此操作不需要一次将其全部加载到内存中。每个值限制为4 TB,每个数据库限制为32 TB。

大型对象有以下缺点:
1.是每个数据库中唯一的大型对象表。
1.当“拥有”记录被删除时,大对象不会自动删除。参见lo模块中的lo_manage函数。
1.由于只有一个表,因此必须逐个记录地处理大对象权限。
1.流式传输比较困难,客户端驱动程序对它的支持也比简单的bytea少。
1.它是系统模式的一部分,因此您只能对分区和表空间等选项进行控制。
我冒昧地猜测,在实际应用中,93%的大型对象都可以通过使用bytea得到更好的服务。

ej83mcc0

ej83mcc04#

我手头上没有大对象和bytea的比较,但请注意,在9.0中切换到十六进制输出格式也是因为它比以前的自定义编码更快。就二进制数据的文本编码而言,您可能不会比目前的速度快多少。
如果这对你来说还不够好,你可以考虑在PostgreSQL客户端和服务器之间使用二进制协议。然后你基本上直接从磁盘中得到这些东西,就像大型对象一样。我不知道PostgreSQL JDBC是否支持这个功能,但快速搜索一下就知道不支持。

相关问题