F.20. lo

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

F.20.1. Rationale

JDBC 驱动程序的问题之一(并且这也影响 ODBC 驱动程序),是该规范假定对 BLOB(二进制大对象)的引用存储在表中,并且如果该条目被更改,则关联的 BLOB 被删除。从数据库中。

就 PostgreSQL 而言,这不会发生。大物件本身就是对象。一个表条目可以通过 OID 引用一个大对象,但是可以有多个表条目引用同一个大对象 OID,因此系统不会仅仅因为您更改或删除了一个这样的条目而删除了该大对象。

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

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

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

F.20.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.20.3. Limitations

  • 删除表仍将孤立其包含的任何对象,因为未执行触发器。您可以通过在DROP TABLE之前加上DELETE FROM table来避免这种情况。

TRUNCATE具有相同的危险。

如果您已经有或怀疑有孤立的大物体,请参阅vacuumlo模块以帮助您清理它们。最好偶尔运行 vacuumlo 作为lo_manage触发器的后盾。

  • 某些前端可能会创建自己的表,而不会创建关联的触发器。同样,用户可能不记得(或不知道)创建触发器。

F.20.4. Author

彼得·蒙特<[email protected]>