1. 程式人生 > >PostgreSQL中的大物件

PostgreSQL中的大物件

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