PostgreSQL 大對象管理指南:pg_largeobject 從原理到實踐

概述

有時候,你可能需要在 PostgreSQL 中管理大對象,例如 CLOB、BLOB 和 BFILE。PostgreSQL 中有兩種處理大對象的方法:一種是使用現有的數據類型,例如用于二進制大對象的 bytea 和用于基于字符的大對象的 text;另一種是使用 pg_largeobject。本文將解釋如何使用 pg_largeobject。

pg_largeobject

pg_largeobject 是 PostgreSQL 提供的大對象解決方案之一,它允許以流式方式訪問存儲在特殊大對象結構中的用戶數據。當處理的數據值過大而無法作為一個整體方便地操作時,流式訪問非常有用。

pg_largeobject 是一個用于存儲實際大對象的系統表。每個大對象在系統表 pg_largeobject_metadata 中都有一個條目。使用 pg_largeobject 管理的大對象可以通過讀/寫 API 進行創建、修改和刪除。pg_largeobject 允許存儲高達 4TB 的大對象。

另一種大對象解決方案是使用現有的數據類型 bytea 和 text,它們基于 TOAST 表構建,限制了大對象的大小為 1GB。

以下是為 pg_largeobject 設計的兩個系統表的架構。

postgres=# \d+ pg_largeobject;Table "pg_catalog.pg_largeobject"Column |  Type   | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
--------+---------+-----------+----------+---------+----------+-------------+--------------+-------------loid   | oid     |           | not null |         | plain    |             |              |pageno | integer |           | not null |         | plain    |             |              |data   | bytea   |           | not null |         | extended |             |              |
Indexes:"pg_largeobject_loid_pn_index" PRIMARY KEY, btree (loid, pageno)
Access method: heappostgres=# \d+ pg_largeobject_metadata;Table "pg_catalog.pg_largeobject_metadata"Column  |   Type    | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
----------+-----------+-----------+----------+---------+----------+-------------+--------------+-------------oid      | oid       |           | not null |         | plain    |             |              |lomowner | oid       |           | not null |         | plain    |             |              |lomacl   | aclitem[] |           |          |         | extended |             |              |
Indexes:"pg_largeobject_metadata_oid_index" PRIMARY KEY, btree (oid)
Access method: heap

pg_largeobject 接口

PostgreSQL 通過 libpq 庫提供客戶端接口來訪問大對象。該接口類似于 Unix 文件系統接口,例如 create、open、read、write、lseek 等。

注意,使用該接口操作大對象時,必須在 SQL 事務塊內進行,因為大對象文件描述符僅在特定事務中有效。以下是與 pg_largeobject 相關的所有接口。

postgres=# \dfS lo*List of functionsSchema   |     Name      | Result data type |    Argument data types    | Type
------------+---------------+------------------+---------------------------+------pg_catalog | lo_close      | integer          | integer                   | funcpg_catalog | lo_creat      | oid              | integer                   | funcpg_catalog | lo_create     | oid              | oid                       | funcpg_catalog | lo_export     | integer          | oid, text                 | funcpg_catalog | lo_from_bytea | oid              | oid, bytea                | funcpg_catalog | lo_get        | bytea            | oid                       | funcpg_catalog | lo_get        | bytea            | oid, bigint, integer      | funcpg_catalog | lo_import     | oid              | text                      | funcpg_catalog | lo_import     | oid              | text, oid                 | funcpg_catalog | lo_lseek      | integer          | integer, integer, integer | funcpg_catalog | lo_lseek64    | bigint           | integer, bigint, integer  | funcpg_catalog | lo_open       | integer          | oid, integer              | funcpg_catalog | lo_put        | void             | oid, bigint, bytea        | funcpg_catalog | lo_tell       | integer          | integer                   | funcpg_catalog | lo_tell64     | bigint           | integer                   | funcpg_catalog | lo_truncate   | integer          | integer, integer          | funcpg_catalog | lo_truncate64 | integer          | integer, bigint           | funcpg_catalog | lo_unlink     | integer          | oid                       | funcpg_catalog | log           | double precision | double precision          | funcpg_catalog | log           | numeric          | numeric                   | funcpg_catalog | log           | numeric          | numeric, numeric          | funcpg_catalog | log10         | double precision | double precision          | funcpg_catalog | log10         | numeric          | numeric                   | funcpg_catalog | loread        | bytea            | integer, integer          | funcpg_catalog | lower         | anyelement       | anymultirange             | funcpg_catalog | lower         | anyelement       | anyrange                  | funcpg_catalog | lower         | text             | text                      | funcpg_catalog | lower_inc     | boolean          | anymultirange             | funcpg_catalog | lower_inc     | boolean          | anyrange                  | funcpg_catalog | lower_inf     | boolean          | anymultirange             | funcpg_catalog | lower_inf     | boolean          | anyrange                  | funcpg_catalog | lowrite       | integer          | integer, bytea            | func

4. 示例

為了更好地理解如何使用 pg_largeobject,以下是一些示例。

創建一個大對象

postgres=# select lo_create(0);lo_create
-----------16384
(1 row)postgres=# select * from pg_largeobject_metadata;oid  | lomowner | lomacl
-------+----------+--------16384 |       10 |
(1 row)postgres=# select * from pg_largeobject;loid | pageno | data
------+--------+------
(0 rows)

導入一個大對象

創建一個簡單的文本文件。

$ echo "this is a test on pg_largeobject." > /tmp/lo_test.txt

將文本文件導入 pg_largeobject。

postgres=*# select lo_import('/tmp/lo_test.txt');lo_import
-----------16385
(1 row)postgres=# select * from pg_largeobject_metadata;oid  | lomowner | lomacl
-------+----------+--------16384 |       10 |16385 |       10 |
(2 rows)

顯示導入 pg_largeobject 后的內容。

postgres=# set bytea_output = 'escape';
SET
postgres=# select * from pg_largeobject;loid  | pageno |                 data
-------+--------+---------------------------------------16385 |      0 | this is a test on pg_largeobject.\012
(1 row)

操作一個大對象

使用 pg_largeobject 的一大優勢是它允許我們修改大對象。以下是一個向另一個大對象追加信息的示例。

begin;
select lo_open(16385, x'60000'::int);
select lo_lseek(0, 32, 0);
select lowrite(0, ', + large object.\012');
commit;postgres=# select * from pg_largeobject;loid  | pageno |                         data
-------+--------+-------------------------------------------------------16385 |      0 | this is a test on pg_largeobject, + large object.\012
(1 row)

這里,x’60000’用于將大對象訪問模式設置為INV_WRITE|INV_READ。這些訪問模式在頭文件 libpq/libpq-fs.h 中定義如下。

#define INV_WRITE               0x00020000
#define INV_READ                0x00040000

將大對象導出到外部文件

除了在 PostgreSQL 內部訪問大對象外,你還可以將大對象導出到外部文件。

postgres=# select lo_export(16385, '/tmp/lo_test_new.txt');

然后,你可以像普通文件一樣檢查內容。

$ cat /tmp/lo_test_new.txt
this is a test on pg_largeobject, + large object.

將操作封裝到函數中

你可以使用 libpq 庫構建函數來自定義大對象的訪問。以下是一個使用 PL/SQL 的簡單示例。

DROP FUNCTION IF EXISTS my_lo_append;
CREATE OR REPLACE FUNCTION my_lo_append(oid, bytea)
RETURNS oid AS $$
DECLAREfd integer;bytes integer;
BEGINfd := lo_open($1, x'60000'::int);bytes := lo_lseek(0, 0, 2);bytes := lowrite(fd, $2);PERFORM lo_close(fd);RETURN $1;
END;
$$ LANGUAGE plpgsql STRICT;

然后調用自定義函數來追加一些信息。

postgres=# select my_lo_append(16385::oid, 'abc123'::bytea);my_lo_append
--------------16385
(1 row)postgres=# set bytea_output = 'escape';
SETpostgres=# select * from pg_largeobject;loid  | pageno |                    data
-------+--------+---------------------------------------------16385 |      0 | this is a test on pg_largeobject.\012abc123
(1 row)postgres=# select lo_export(16385, '/tmp/lo_test_new.txt');lo_export
-----------1
(1 row)

你還可以檢查導出后作為文件操作的大對象。

$ cat /tmp/lo_test_new.txt
this is a test on pg_largeobject.
abc123

總結

在本文中,我解釋了如何使用 pg_largeobject 來處理 PostgreSQL 中的大對象,并提供了一些非常簡單的示例。希望這能有所幫助。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96537.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96537.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96537.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

算法第四題移動零(雙指針或簡便設計),鏈路聚合(兩個交換機配置)以及常用命令

save force關閉導出dis vlandis ip int bdis int bdis int cudis thisdis ip routing-table(查路由表)int bridge-aggregation 1(鏈路聚合,可以放入接口,然后一起改trunk類。)穩定性高

告別繁瑣配置!Retrofit-Spring-Boot-Starter讓HTTP調用更優雅

01 引言 之前分享過一篇文章【像調用接口一樣調用第三方API】,今天迎來了新成員Retrofit。 retrofit-spring-boot-starter 是一個基于 Spring Boot 的 starter,它簡化了 Retrofit 在 Spring 環境中的集成和使用。Retrofit 本身是一個類型安全的 HTTP 客…

60_基于深度學習的羊群計數統計系統(yolo11、yolov8、yolov5+UI界面+Python項目源碼+模型+標注好的數據集)

目錄 項目介紹🎯 功能展示🌟 一、環境安裝🎆 環境配置說明📘 安裝指南說明🎥 環境安裝教學視頻 🌟 二、數據集介紹🌟 三、系統環境(框架/依賴庫)說明🧱 系統環…

代理服務器是什么?怎么選擇?

代理服務器是一種位于用戶設備與目標網絡之間的中間服務器,通過接收用戶請求、轉發至目標網絡并將結果返回給用戶,實現“用戶→代理服務器→目標網絡”的間接訪問。其核心功能圍繞“網絡優化”“訪問控制”與“身份隱藏”展開,為個人與企業用…

代碼隨想錄刷題Day56

子集 這道題求子集,集合的基本運算之一,按照高中數學學習集合的知識,可以把這個找冪集的過程按照元素的個數來劃分步驟。也就是先找零個元素的子集,再找一個元素的子集,再找兩個元素的子集...一直到找N個元素的集合為…

pycharm——關于Pyqt5

PyQt5新手教程(七萬字) import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QInputDialog, QColorDialog, QFontDialog, QFileDialog, QProgressDialog, QMessageBox from PyQt5.QtCore i…

P2678 [NOIP 2015 提高組] 跳石頭

P2678 [NOIP 2015 提高組] 跳石頭 判斷條件該怎么寫

小麥矩陣系統:一鍵批量發,多賬號同步不掉鏈

隨著互聯網的發展和社交平臺的普及,企業和個人用戶越來越依賴社交媒體平臺來進行信息傳播、品牌宣傳以及市場推廣。在這個信息高速流動的時代,如何更高效地管理多個社交平臺的賬號,并保持信息的同步與流暢傳播,成為了許多企業面臨…

JavaScript經典面試題二(函數和作用域)

目錄 一、閉包,使用場景 1.閉包的定義 2.閉包的實現原理 3.閉包的應用場景 (1)數據封裝與私有變量 (2)函數柯里化 (3)事件處理與回調 (4)模塊化開發 4.注意事項 …

Linux防火墻iptables

目錄 一,Iptables概述 二,iptables組成 1,表 2,鏈 3,鏈表對應關系 4,數據包過濾的匹配流程 5,規則匹配策略 三,iptables防火墻配置 1,iptables命令 2&#xff…

[優選算法專題二——NO.16最小覆蓋子串]

題目鏈接 LeetCode最小覆蓋子串 題目描述 代碼編寫 、關鍵注意點 僅統計目標相關字符:通過 hash1.count(in) 判斷字符是否在 t 中,避免無關字符(如 s 中的 D、E)干擾統計,提升效率。count 的更新時機:僅當…

考研408計算機網絡近年第34題真題解析(2021-2024.34)

(2021.34)此題已明確為差分曼徹斯特編碼,通常第一個時間間隙可能不太好判斷,因為0,或1可以變化,但差分曼徹斯特編碼的其它位置可以判斷,圖中黃色數字的時間間隙位置,開始位置和前面一…

微信小程序開發教程(八)

目錄:1.全局配置-tabBar2.小程序的頁面配置3.數據請求-GET和POST請求4.數據請求-request請求的注意事項1.全局配置-tabBar注意tabar頁面必須放到Page頭部位置2.小程序的頁面配置3.數據請求-GET和POST請求4.數據請求-request請求的注意事項

日語學習-日語知識點小記-構建基礎-JLPT-N3階段(29):文法運用第9回3+(考え方11)

日語學習-日語知識點小記-構建基礎-JLPT-N3階段(31):文法運用第9回31、前言(1)情況說明(2)工程師的信仰2、知識點1ー 復習2ー 單詞訓練3、單詞(1)日語單詞  …

小鵬汽車在 VLA(視覺 - 語言 - 動作)算法模型框架細節與原理

小鵬汽車的 VLA(視覺 - 語言 - 動作)算法模型框架是其端到端自動駕駛系統的核心,融合了多模態感知、語言推理與動作生成能力。以下是其技術細節與原理的深度解析: 一、整體架構:混合式端到端設計 小鵬 VLA 采用云端基座…

京東商品詳情 API 全解析:合規對接與 B2C 場景實戰指南

在 B2C 電商運營中,商品詳情數據是支撐店鋪管理、庫存調控、營銷決策的核心基礎。京東商品詳情 API 作為官方合規的數據獲取通道,不僅能穩定返回商品標題、價格、庫存等關鍵信息,還針對 B2C 場景新增了預售鎖庫、次日達標識等特色字段。本文從…

【Visual Studio 2017 和 2019下載】

Visual Studio 2017 和 2019下載VS2017下載地址:VS2019下載地址:VS2017下載地址: Visual Studio 2017 Community 鏈接 Visual Studio 2017 Enterprise 鏈接 VS2019下載地址: Visual Studio 2019 Community 鏈接 Visual Studio …

Python 輕松實現替換或修改 PDF 文字

在日常開發或文檔處理過程中,經常會遇到需要對 PDF 文檔中的文字進行修改的場景。例如更新合同條款、修正報表數據,或者批量替換文件中的特定內容。由于 PDF 格式以固定排版為特點,直接修改文字不像 Word 那樣直觀,因此需要借助專…

CI/CD流水線優化實戰:從30分鐘到5分鐘的效能革命

關鍵詞:CI/CD優化、GitHub Actions、Jenkins、自動化部署、流水線加速 一、引言:CI/CD流水線為何需要優化? 在現代軟件開發中,CI/CD(持續集成/持續交付)已成為DevOps實踐的核心環節。然而,許多團隊的流水線存在效率低下問題,??平均構建時間超過30分鐘??,嚴重制約…

神經網絡矩陣的點乘與叉乘概述

點乘點乘:兩個矩陣對應位置元素相乘(逐元素級 element - wise)實現方式:可通過 * 和 torch.mul(x, y) 函數實現(含廣播機制)模型符號:一個圓圈中間加一個實心點叉乘叉乘:傳統線性代數…