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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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) 函数实现(含广播机制)模型符号:一个圆圈中间加一个实心点叉乘叉乘:传统线性代数…