PostgreSQL中的大对象

版权声明:本文为博主原创之文章,未经博主允许谢绝转载。 https://blog.csdn.net/pg_hgdb/article/details/83149617

PostgreSQL具有大对象的功能,它提供了对于存储在一个特殊大对象结构中的用户数据的流式访问。

所有的大对象都存在一个名为pg_largeobject的系统表中。每一个大对象还在系统表pg_largeobject_metadata中有一个对应的项。大对象可以通过类似于标准文件操作的读/写API来进行创建、修改和删除。

自PostgreSQL 9.0起,读取一个大对象需要SELECT权限,而写或者截断一个大对象则需要UPDATE权限。只有大对象的拥有者(或者一个数据库超级用户)可以创建大对象、注释大对象或修改大对象的拥有者。

大对象的实现将大对象分解成很多“数据块”并且将这些数据块存储在数据库的行中。使用一个B-tree索引用来保证在进行随机访问读写时能够根据数据块号快速地搜索到正确的数据块。

接着,我们介绍一下PostgreSQL的libpq客户端接口为访问大对象所提供的功能。PostgreSQL的大对象接口按照Unix文件系统的接口建模,也有相似的open、read、write、lseek等。所有使用这些函数对大对象的操作都必须发生在一个SQL事务块中,因为大对象文件描述符只在事务期间有效。

postgres=# create table image(name text, raster oid);
CREATE TABLE
postgres=# select lo_creat(-1);
 lo_creat 
----------
    49727
(1 row)

创建一个新的大对象。其返回值是分配给这个新大对象的OID或者InvalidOid(0)表示失败。

postgres=# select lo_create(43213);
 lo_create 
-----------
     43213
(1 row)

尝试创建OID为43213的大对象,返回值是分配给新大对象的OID或InvalidOid(0)表示发生错误。lo_create是从PostgreSQL 8.1版本中开始提供的函数,如果该函数在旧服务器版本上运行,它将失败并返回InvalidOid。

postgres=# select lo_unlink(43213);
 lo_unlink 
-----------
         1
(1 row)

从数据库中移除OID为43213的大对象,成功时返回1,失败时返回-1

postgres=# insert into image values('beautiful image',lo_import('/opt/1'));
INSERT 0 1

将一个操作系统文件导入成一个大对象。注意该文件是被客户端接口库而不是服务器所读取,因此它必须存在于客户端文件系统中并且对于客户端应用是可读的。

postgres=# select lo_export(image.raster,'/tmp/1') from image where name = 'beautiful image';
 lo_export 
-----------
         1
(1 row)

把一个大对象导出到一个操作系统文件,注意该文件是被客户端接口库而不是服务器写入。成功返回1,错误返回-1

服务器端的lo_import和lo_export函数和客户端中有不相同的行为。这两个函数从服务器的文件系统中读和写文件,使用的是数据库所有者的权限。因此,它们的使用被限制于超级用户。相反,客户端的导入和导出函数读写的是客户端的文件系统,使用的是客户端程序的权限。因此客户端函数不需要超级用户权限。

函数lo_read和 lo_write的功能也可以在服务器端调用,但是在服务器端的名称与客户端接口不同:它们的名称中不包含下划线。必须以loread和lowrite的名字调用这些函数。

 

By kalath

猜你喜欢

转载自blog.csdn.net/pg_hgdb/article/details/83149617