在PostgreSQL中存储文件是否存在性能问题?

Ren*_*ani 38 postgresql blob file bytea

可以在PostgreSQL的表中存储像HTML页面,图像,PDF等文件,或者它很慢?我读了一些文章说这不推荐,但我不知道是否属实.

什么是更好的使用,存储为BLOB(它存储在文件中,对吗?)或存储bytea类型?

Dan*_*ons 54

你基本上有两个选择.您可以将数据存储在行中,也可以使用大型对象工具.由于PostgreSQL现在使用称为TOAST的东西将大字段移出表格,因此直接在行中存储大数据不会产生性能损失.字段大小仍有1 GB的限制.如果这个太有限或者您想要一个流API,您可以使用大对象工具,它可以为您提供更像数据库中的文件描述符.将LO ID存储在列中,可以从该ID读取和写入.

我个人建议你避免使用大型物体设施,除非你绝对需要它.使用TOAST,只需使用您期望的数据库即可覆盖大多数用例.对于大型物体,您会给自己额外的维护负担,因为您必须跟踪您使用过的LO ID,并确保在不再使用它们时(但之前不再使用它们)取消链接它们或者它们将放在您的数据目录永远占用空间.还有很多设施都有特殊的行为,其中的细节让我感到厌烦,因为我从不使用它们.

对于大多数人来说,与在数据库中存储大数据相关的巨大性能损失是,您的ORM软件将在每个查询中提取大数据,除非您明确指示不这样做.您应该注意告诉Hibernate或者您正在使用的任何内容将这些列视为大型,并且仅在特别请求时才获取它们.

  • 如果bytea数据很小,则bytea数据将默认存储在表中,并移动到辅助("toast")表并压缩为更大的值.请参阅:http://www.postgresql.org/docs/9.1/static/storage-toast.html以获取介绍.您可以禁用辅助存储的压缩,这将提高仅获取部分值的性能. (2认同)
  • 最好在这篇文章中插入一些关于 PSQL 备份所用时间的内容。它是否需要更长的时间?听起来不像。 (2认同)

小智 13

BLOB(LO)类型在标准PostgreSQL堆页面中以2KB块的形式存储数据,默认大小为8KB.它们不会作为独立,有凝聚力的文件存储在文件系统中 - 例如,您将无法找到该文件,进行逐字节比较并期望它与您原始文件数据相同加载到数据库中,因为还有Postgres堆页面标题和结构,用于描述块.

如果您的应用程序需要频繁更新二进制数据,您应该避免使用大对象(LO)接口,特别是如果它涉及大量小的随机访问写入,这是由于PostgreSQL实现并发控制(MVCC)的方式在您对数据库进行VACUUM之前,可能会导致使用的磁盘空间量激增.相同的结果可能也适用于以bytea类型甚至TOAST的内联存储在列中的数据.

但是,如果您的数据遵循"一次写入多次读取"模式(例如,上传PNG图像并且之后从不对其进行修改),则从磁盘使用的角度来看应该没问题.

有关进一步的讨论,请参阅此pgsql-general邮件列表线程.