4.7.8. BLOB

El tipo de datos BLOB (Binary Large OBject) permite almacenar en una columna un objeto de gran tamaño. PostgreSQL no conoce nada sobre el tipo de información que se almacena en una columna BLOB, simplemente lo considera como una secuencia de bytes. Por este motivo, no se tienen operaciones sobre los tipos BLOB, con la excepción del operador de concatenación, que simplemente une el contenido de dos BLOB en uno.

Veamos cómo almacenar una fotografía en una tabla de personas mediante tipos BLOB.

Una primera manera de hacerlo es importando el contenido del archivo que contiene la imagen mediante la función lo_import():

demo=# select lo_import(`/home/quiron/mi-foto.jpg´);
lo_import
-----------
17425
(1 row)

 

Esta función devuelve como resultado el OID del objeto insertado.¿Dónde se ha almacenado la fotografía si no hemos utilizado el comando insert? Post- greSQL mantiene una tabla de nombre pg_largeobject con el objetivo de almacenar BLOB. Podemos utilizar el OID para hacer referenciar al objeto en una tabla:

demo=# create table persona (
demo(# nombre varchar(30),
demo(# direccion varchar(30),
demo(# fotografia oid
demo(# );
CREATE

Los registros insertados en esta tabla llevan un número entero como OID que, en el siguiente caso, se ha obtenido solicitándolo a la función lo_import() anterior.

demo=# insert into persona values (`Julio´ , `Cedro 54´, 17425);

La inserción anterior pudo haberse realizado en un solo paso:

 

demo=# insert into persona
values ( `Julio´ , `Cedro 54´, lo_import(`/home/quiron/mi-foto.jpg´));

Para extraer el contenido de la columna, se utiliza la función lo_export()

demo=# select lo_export(17425,`/tmp/mi-foto.jpg´);
lo_export
-----------
1
(1 row)

La función lo_unlink() permite borrar un BLOB almacenado en pg_largeobject:

select lo_unlink(17425);

 

Veamos el formato que utiliza PostgreSQL para visualizar BLOB.

Se ha recortado la salida para hacer más comprensible la tabla.

loid  | pageno | data
------+--------+------------------------------------------------------------------
17425 | 0      | \377\330\377\340\000\020JFIF\000\001\001\001\000H\000H\000\000\37
17425 | 1      | \256-}\306\267\032s[\336)\245\231\370|L\206\275\364\224\321\237\2
17425 | 2      | \341\226;\015l\232\033f\\\371\251\0323\003t\307\207~\035GB\271\17
(3 rows)

La fotografía se ha dividido en tres registros, que son las páginas 0, 1 y 2 del BLOB. Los tres registros tienen el mismo loid, lo que significa que son el mismo objeto. Obsérvese también, que los bytes son desplegados como caracteres de la forma ‘\ddd’, donde ddd son tres dígitos octales.

Para almacenar un BLOB en una tabla de forma directa; es decir, sin utilizar la tabla del sistema pg_largeobject utilizamos el tipo de dato bytea:

 

En el primer caso se está insertando un BLOB de un solo byte, el carácter ASCII cero.

En el segundo caso se están insertando 4 bytes, los tres primeros están representados directamente por los caracteres imprimibles ASCII y el tercero, el caracter ASCII 30 octal, como no es imprimible, se escribe
en notación ‘\\ddd’.

 

demo=# create table persona (
demo(# nombre varchar(30),
demo(# direccion varchar(30),
demo(# fotografia bytea
demo(# );
CREATE

 La columna fotografía es de tipo bytea, lo que permite almacenar objetos de gran tamaño, cerca de 1GB. Para insertar valores en estas columnas, hacemos lo siguiente:

demo=# insert into persona values ( `Jorge´ , `Cerezo 55´, `\\000´);
INSERT 17436 1
demo=# insert into persona values ( `Luis´ , `Encino 67´, `abc\\030´);
INSERT 17437 1

La consulta se visualiza como sigue:

demo=# select * from persona;
nombre  | direccion | fotografia
--------+-----------+------------
Jorge   | Cerezo 55 | \000
Luis    | Encino 67 | abc\030
(2 rows)

 

Los caracteres en notación octal se muestran con una barra invertida y con dos tal como se escribieron. Esto es debido a que, en realidad, sólo llevan una barra invertida, pero por cuestiones de diseño PostgreSQL, las literales BLOB deben escribirse con doble barra invertida.