PostgreSQL 操作大对象

前言

通常来说在关系型数据库中保存大对象有如下方式:

  • 使用Blob或者Clob类型的字段,将大对象的内容保存到数据表中。
  • 将大对象保存为文件放置到文件系统中。数据表只保存指向该文件系统的路径。

PG中没有提供MySQL或者Oracle中的Blob,Clob类型的字段。但PG提供的大对象处理方式简化了上述的方法2,无需人工去上传文件到文件系统然后再保存路径。将大对象直接上传到PG后,该对象本身的存储和生成该对象引用的过程无需使用者再费心。

接下来为大家介绍PG操作大对象的方式。

上传大对象

SELECT lo_from_bytea(%s, %s::bytea) as loid;

其中第一个参数为loid(Large object ID)。如果设定为0,则使用一个空闲的loid并返回。
第二个参数为大对象的byte数组。

获取大对象

SELECT lo_get(%s) as "data";

需要的参数为loid,即第一步上传大对象返回的结果。

删除大对象

SELECT lo_unlink(%s);

参数为loid。
返回1表示删除成功,-1表示删除失败。

查询PG中保存的所有大对象

select * from pg_largeobject;

该表包含如下字段:

  • loid: 大对象的id。
  • pageno: 保存大对象的页数。
  • data: 大对象的数据(字节数组)。

通过如下语句可以查询到大对象的元数据:

select * from pg_largeobject_metadata;

该表包含如下字段:

  • oid: 大对象的id。
  • lomowner: 大对象的属主。
  • locacl: 大对象的ACL(访问控制列表,权限相关)。

使用示例

首先使用lo_from_bytea函数上传大对象到pg。例如:

select lo_from_bytea(0, '\xffffff00')

该SQL执行成功之后会返回上传大对象的id(loid)。

这个ID相当于该大对象的身份信息,即以后查询,修改或者删除该大对象都要使用该ID。因此需要将他保存在业务表当中。

例如我们上传的大对象为文件内容。我们有如下文件表:

CREATE TABLE file (
    create_time timestamptz NOT NULL,
    update_time timestamptz NOT NULL,
    id uuid NOT NULL,
    file_name varchar(256) NOT NULL,
    loid int4 NOT NULL,
    meta jsonb NOT NULL
);

在上传完大对象之后,需要将返回的loid值保存在file表的loid字段中。

其他操作大对象的函数

  • lo_put ( loid oid, offset bigint, data bytea ) → void:从offset处开始写入数据。如果新写入的数据比原来大对象从offset到结尾的数据量要大,大对象会自动扩大
  • lo_get ( loid oid [, offset bigint, length integer ] ) → bytea:从offset出读取数据,读取长度为length。
  • lo_creat( loid oid ) → oid:新建一个空的大对象。返回大对象的oid。如果传入的参数为-1,则系统自动指定一个空闲的loid,然后返回。
  • lo_import ( filename text ) → oid:导入PG服务器上的某个文件到PG,返回该大对象的oid。注意事项:因为涉及到服务器上数据的读写。因此不建议赋予普通用户使用该函数的权限。
  • lo_export ( loid oid, filename text ) → int:导出大对象夫到PG服务器上指定文件,返回导出文件的长度。注意事项同上。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容