2025年9月25日: PostgreSQL 18 发布!
支持版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 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 引用列的表来解决此问题。该触发器实际上只是在删除或修改引用大对象的该值时执行 lo_unlink。当你使用此触发器时,你假定任何在受触发器控制的列中引用的对象只有一个数据库引用!

该模块还提供了一个数据类型 lo,它实际上只是一个关于 oid 类型的 。这对于区分存储大对象引用的数据库列与存储其他事物 OID 的列很有用。你不必使用 lo 类型来使用触发器,但使用它来跟踪数据库中哪些列代表你正在使用触发器管理的大对象可能很方便。也有传言说,如果 BLOB 列不使用 lo 类型,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

提交更正

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