ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# F.20\. lo `lo`模块为管理大对象(也叫做LO或BLOB)提供支持。 包括数据类型`lo`和触发器`lo_manage`。 ## F.20.1\. 原理 JDBC驱动的问题之一(也影响ODBC驱动),是规范假设BLOB(二进制大对象)的参数是存储在一个表内的, 并且如果该项改变了,那么相关的BLOB会从数据库中删除。 作为PostgreSQL标准,这个不会发生。大对象被视为对象; 一个表项可以通过OID引用一个大对象,不过可能多个表项引用同一个大对象OID, 所以系统不会因为你改变或删除一个表项就删除大对象。 这对PostgreSQL专有应用来说很好,但是使用JDBC或ODBC的标准代码不会删除大对象, 导致孤独的对象—对象不被任何东西引用,只是简单的占用磁盘空间。 `lo`模块允许通过在包含LO引用字段的表上附加一个触发器修复这个问题。 该触发器本质上只是在你删除或修改一个引用大对象的值时做`lo_unlink`。 当使用这个触发器时,假设只有一个数据库引用被触发器控制字段引用的任意的大对象。 该模块也支持数据类型`lo`,该类型实际上只是一个`oid`类型的域。 这对于区别持有大对象引用的数据库字段和那些其他事情的OID有帮助。 你不必使用`lo`类型来使用该触发器, 但是使用它会很方便的记录你的数据库中的哪个字段代表管理该触发器的大对象, 如果你不为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 PROCEDURE lo_manage(raster); ``` 对于每个将要包含大对象的唯一引用的字段,创建一个`BEFORE UPDATE OR DELETE` 触发器,并将字段名作为触发器唯一的参数。你也可以通过使用`BEFORE UPDATE OF` `_column_name_` 限制触发器只在该字段更新时执行。如果你在相同的表中需要多个`lo`字段, 那么为每个字段创建一个单独的触发器,记得给相同表上的每个触发器以不同的名字。 ## F.20.3\. 限制 * 删除一个表仍然将孤立它包含的任意对象,因为触发器没有执行。你可以通过在`DROP TABLE`之前`DELETE FROM` `_table_`来避免这个问题。 `TRUNCATE`有同样的危险。 如果你已经有或者怀疑你有孤立的大对象,参阅[vacuumlo](#calibre_link-631) 模块帮助你清除它们。偶尔运行[vacuumlo](#calibre_link-631) 作为`lo_manage`触发器的后备是一个好主意。 * 一些前端可能创建他们自己的表,并且不创建相关的触发器。还有,用户可能不记得(或知道) 创建触发器。 ## F.20.4\. 作者 Peter Mount `<[peter@retep.org.uk](mailto:peter@retep.org.uk)>`