【问题标题】:Function to add to bytea blob in postgresql在 postgresql 中添加到 bytea blob 的函数
【发布时间】:2014-01-12 11:28:58
【问题描述】:

我正在将大量文件(二进制数据)加载到 Postgres 数据库中(这些文件作为 blob 存储在数据库中)。

我发现的一种方法是使用大对象,效果很好。但是,出于各种原因,我想探索将文件内容直接存储在 bytea 字段中的可能性。 现在,大对象管理器允许我直接将字节块直接写入其缓冲区,无需先将整个文件加载到内存中。

这对我来说相当重要,因为我在加载文件时有多个并行工作的线程(如果所有线程同时将整个文件加载到内存中,GC 就无法跟上)。

有什么方法可以使用 bytea 参数来做到这一点?我在考虑一个 SQL 函数,它将一大块字节附加到一行的 bytea 字段。然后我可以重复调用这个函数来获取一个 blob。我对 PostgreSQL 比较陌生,所以我真的可以提示这样一个 SQL 函数的外观。

那么,我如何在 PostgreSQL 中附加到一个 bytea blob?

顺便说一句,其他想法也值得赞赏。

我正在使用 PostgreSQL 9.3、C# (.NET 4) 和 NpgSql Postgres 数据提供程序,文件 (blob) 可以是从几 kb 到几 mb 的所有内容。

编辑:我看到了对 byteacat 函数的引用,看起来很有希望,但我找不到如何使用它的示例。

Edit2:最后,在查询中将 blob 作为单个参数加载似乎是最简单的......只要确保它们足够快地被垃圾收集(例如,不使字节数组成为对象的属性)。 Postgresql 处理数据非常好!

【问题讨论】:

    标签: c# sql postgresql blobs


    【解决方案1】:

    编辑:Daniel Vérité 是对的,这会变得一团糟(一段时间后会大幅减速), 我不会推荐这条路。

    好吧,真的很简单:

    有一个||附加二进制数据的运算符...示例:

    UPDATE TableWithBlob SET blob = blob || E'123\\000456' WHERE id = 'a356211f-1cb7-436d-80a8-7e608ffds0';
    

    或作为参数化 SQL 查询(使用 NpgSQL 数据提供程序时):

    UPDATE TableWithBlob SET blob = blob || @Data WHERE ID = @ID;
    

    【讨论】:

    • 请注意,对于较大的值,它的效率非常低。每次更新都会解压缩旧值,附加新部分,压缩新值,并将其写入新的物理行。提交之后,autovacuum 会将“死行”的空间标记为可重用。
    • 我注意到...有什么更好的解决方案吗?
    • 如果可能,将 bytea 内容拆分为如下表:(fk_id text or int, chunk_number int, chunk_data bytea)。实际上,这看起来像pg_largeobject,除了它的 2Kb 块,几十年来没有改变,现在太小了。我建议128Kb的倍数
    • 这是可能的,但不是我想要的(似乎不如大型对象好)。也许如果我能以某种方式再次合并表中的值,但这可能是一件复杂的事情。
    猜你喜欢
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多