2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不受支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.21. lo — 管理大对象 #

lo 模块提供对管理大对象(也称为 LO 或 BLOB)的支持。这包括数据类型 lo 和触发器 lo_manage

此模块被认为是 受信任的,也就是说,它可以由非超级用户安装,这些用户对当前数据库具有 CREATE 权限。

F.21.1. 理念 #

JDBC 驱动程序(以及 ODBC 驱动程序)的问题之一是,规范假设对 BLOB(二进制大型对象)的引用存储在表中,如果该条目更改,则与该 BLOB 关联的数据将从数据库中删除。

按照 PostgreSQL 的现状,这种情况不会发生。大对象被视为独立的对象;表条目可以通过 OID 引用大对象,但可以有多个表条目引用相同的大对象 OID,因此系统不会仅仅因为您更改或删除其中一个条目就删除大对象。

现在,对于 PostgreSQL 特定的应用程序来说,这很好,但是使用 JDBC 或 ODBC 的标准代码不会删除对象,从而导致孤立对象——没有被任何东西引用的对象,并且只占用磁盘空间。

lo 模块允许通过将触发器附加到包含 LO 引用列的表来解决此问题。触发器本质上只会在您删除或修改引用大对象的 value 时执行 lo_unlink。当您使用此触发器时,您假设在触发器控制的列中,只有一个数据库引用任何大对象!

该模块还提供了一种数据类型 lo,它实际上只是在 oid 类型上的 。这对于区分保存大对象引用的数据库列和其他东西的 OID 的数据库列很有用。您不必使用 lo 类型来使用触发器,但使用它来跟踪数据库中哪些列表示您使用触发器管理的大对象可能很方便。据说,如果您不将 lo 用于 BLOB 列,ODBC 驱动程序会感到困惑。

F.21.2. 如何使用它 #

这是一个简单的用法示例

CREATE TABLE image (title text, raster lo);

CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
    FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);

对于每个将包含对大对象的唯一引用的列,创建一个 BEFORE UPDATE OR DELETE 触发器,并将列名作为唯一的触发器参数。您还可以通过使用 BEFORE UPDATE OF column_name 将触发器限制为仅在更新列时执行。如果您需要在同一表中使用多个 lo 列,则为每个列创建一个单独的触发器,并记住为同一表上的每个触发器指定不同的名称。

F.21.3. 限制 #

  • 删除表将仍然使它包含的任何对象成为孤儿,因为触发器没有被执行。您可以通过在 DROP TABLE 前面添加 DELETE FROM table 来避免这种情况。

    TRUNCATE 具有相同的风险。

    如果您已经拥有或怀疑您拥有孤立的大对象,请参阅 vacuumlo 模块以帮助您清理它们。最好定期运行 vacuumlo 作为对 lo_manage 触发器的后备。

  • 一些前端可能会创建自己的表,并且不会创建关联的触发器。此外,用户可能不记得(或不知道)创建触发器。

F.21.4. 作者 #

Peter Mount

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符或需要进一步澄清,请使用 此表格 报告文档问题。