【问题标题】:Appropriate column type for storing 16K binary blocks in PostgreSQL在 PostgreSQL 中存储 16K 二进制块的适当列类型
【发布时间】:2015-09-26 08:55:07
【问题描述】:

我的应用程序需要在 Postgres 数据库中存储数百万个二进制块(每秒可能到达数千个)。大多数块的大小为 16K,尽管有些块可能更小。我知道我可以使用 text、bytea 或 blob 列,或者我可以将二进制数据存储在数据库外部的文件中,并将它们的路径放在表中。

考虑到高写入吞吐量是我最重要的目标,哪个选项最适合我的情况?

【问题讨论】:

  • 如果这些块是可压缩的(即具有重复值),那么bytea 可能是一个不错的选择,因为它会压缩数据。但我同意汤姆的观点:您必须自己测试性能,这是不可能以“一般”方式回答的。我个人会先测试bytea的方案,看看能不能支持性能要求
  • 对不同的方法进行基准测试当然是我的议程。我只是想知道那里有一些我不知道的众所周知的事实。

标签: database postgresql throughput


【解决方案1】:

bytea 是这里的明智选择——几乎是唯一的选择。

使用textvarchar没有优势。不要在其中存储编码的二进制文件。这是一个你应该立即忽略的选项。

PostgreSQL 中没有 blob 类型。我想您可能指的是lob,它是oid 的包装器,用于在pg_largeobject 表中查找“大对象”。当您需要在数据库中查找、覆盖、追加等虚拟“文件”时,这很有用,但它根本不适合您的用例。

可以存储路径或文件名,然后在外部查找它们,但您将拥有很多非常小的文件。您还需要一个侧通道供客户端读取和写入它们,因为您不能直接使用 PostgreSQL 协议。您需要分别为它们处理备份/恢复和复制。如果事务回滚或相应的数据库元组被删除,它们不会被删除,因此您需要一个清理系统来删除不再需要的文件。会变得乱七八糟。当文件很大、寿命长且大部分是静态的时,这是值得做的,但听起来不像你的情况。

直接将二进制存储在bytea列中,最好使用PgJDBC或libpq中的二进制协议支持在客户端和服务器之间交换字节值而不需要编码。在您写入的表上具有最少的索引。 (在某些情况下,您甚至可以不定义主键,但这是一种专家级选项)。如果您不介意在计划外重新启动时丢失表中的数据,请使用未记录的表。否则批量写入并使用异步提交和/或提交延迟。

另见How to speed up insertion performance in PostgreSQL

【讨论】:

  • 这正是我正在寻找的答案。谢谢你。关于在libpq中使用二进制协议支持,使用PQexecParams并要求paramFormats中的二进制格式是否足够?
  • @Elektito 是的,这很适合阅读。对于编写,您必须为查询参数指定参数格式数组
【解决方案2】:

尝试所有选项,对它们进行基准测试,然后找出最适合您的选项。

【讨论】:

    猜你喜欢
    • 2021-06-13
    • 2018-10-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 2019-09-27
    • 1970-01-01
    相关资源
    最近更新 更多