↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3
历史版本。 PostgreSQL 8.3 已结束支持。 请参阅 当前版本手册.

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

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

F.14.1. 原理

JDBC 驱动的一个问题是(ODBC 驱动也受此影响),其规范假定对 BLOB(二进制大对象)的引用存储在表内,并且如果该表项被更改,相关的 BLOB 就会从数据库中删除。

但在目前的PostgreSQL中并非如此。大对象被视为独立对象;表中的一个项可以通过 OID 引用某个大对象,但也可能有多个表项引用同一个大对象 OID,因此系统不会仅因你更改或删除了其中一个表项就删除该大对象。

这对于PostgreSQL专用应用没有问题,但使用 JDBC 或 ODBC 的标准代码不会删除这些对象,从而产生孤立对象,也就是不再被任何内容引用、只是占用磁盘空间的对象。

lo模块允许通过把触发器附加到包含 LO 引用列的表上来解决这个问题。该触发器本质上就是在你删除或修改引用大对象的值时调用lo_unlink。使用这个触发器时,你实际上是假定:凡是出现在受该触发器控制的列中的大对象,在数据库中都只有一个引用!

该模块还提供了数据类型lo,它实际上只是oid类型的一个域。这有助于区分保存大对象引用的数据库列与保存其他对象 OID 的列。使用该触发器并不要求必须使用lo类型,但用它来标识数据库中哪些列表示由该触发器管理的大对象,可能会更方便。还有传言说,如果 BLOB 列不用lo,ODBC 驱动会感到困惑。

F.14.2. 如何使用

下面是一个简单的用法示例:

   CREATE TABLE image (title TEXT, raster lo);

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

对于每个将保存指向大对象的唯一引用的列,创建一个 BEFORE UPDATE OR DELETE 触发器,并将该列名作为唯一的触发器参数。如果同一张表中需要多个 lo 列,就为每一列分别创建一个触发器,并记得为同一张表上的每个触发器指定不同的名称。

F.14.3. 限制

  • 删除表时,其中包含的任何对象仍会变成孤立对象,因为这种情况下不会执行触发器。为避免这种情况,可以先执行DELETE FROM table,再执行DROP TABLE。

    TRUNCATE也有同样的风险。

    如果你已经有(或怀疑有)孤立的大对象,可以参见 contrib/vacuumlo 模块(第 F.33 节)来帮助清理它们。作为 lo_manage 触发器的兜底措施,建议偶尔运行一次 vacuumlo。

  • 某些前端可能会创建自己的表,但不会创建相应的触发器。此外,用户也可能不记得(或根本不知道)要创建这些触发器。

F.14.4. 作者

Peter Mount

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.