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

提交更正

如果你在文件中發現任何不正確、與你的特定功能體驗不符或需要進一步澄清的內容,請使用 此表格 報告文件問題。