F.21. lo — gestionar objetos grandes (large objects) #

F.21.1. Justificación
F.21.2. Cómo usarlo
F.21.3. Limitaciones
F.21.4. Autor

El módulo lo proporciona soporte para gestionar objetos grandes (también llamados LO o BLOB). Esto incluye un tipo de datos lo y un disparador (trigger) lo_manage.

Este módulo se considera «confiable» (trusted), es decir, puede ser instalado por no superusuarios que tengan el privilegio CREATE en la base de datos actual.

F.21.1. Justificación #

Uno de los problemas con el controlador JDBC (y esto también afecta al controlador ODBC) es que la especificación asume que las referencias a BLOB (Binary Large OBjects) se almacenan dentro de una tabla y, si esa entrada cambia, el BLOB asociado se elimina de la base de datos.

Tal como funciona PostgreSQL, esto no ocurre. Los objetos grandes se tratan como objetos por derecho propio; una entrada de tabla puede hacer referencia a un objeto grande por su OID, pero puede haber múltiples entradas de tabla que hagan referencia al mismo OID de objeto grande, por lo que el sistema no elimina el objeto grande simplemente porque cambies o elimines una de esas entradas.

Esto está bien para aplicaciones específicas de PostgreSQL, pero el código estándar que usa JDBC o ODBC no eliminará los objetos, lo que resulta en objetos huérfanos — objetos que no están referenciados por nada y simplemente ocupan espacio en disco.

El módulo lo permite solucionar esto asociando un disparador a las tablas que contienen columnas de referencia a LO. El disparador esencialmente solo hace un lo_unlink cada vez que eliminas o modificas un valor que hace referencia a un objeto grande. ¡Cuando usas este disparador, estás asumiendo que solo hay una referencia en la base de datos para cada objeto grande que está referenciado en una columna controlada por el disparador!

El módulo también proporciona un tipo de datos lo, que en realidad es solo un dominio sobre el tipo oid. Esto es útil para diferenciar las columnas de la base de datos que contienen referencias a objetos grandes de aquellas que son OIDs de otras cosas. No tienes que usar el tipo lo para usar el disparador, pero puede ser conveniente usarlo para llevar un registro de qué columnas en tu base de datos representan objetos grandes que estás gestionando con el disparador. También se rumorea que el controlador ODBC se confunde si no usas lo para las columnas BLOB.

F.21.2. Cómo usarlo #

Aquí tienes un ejemplo simple de uso:

CREATE TABLE image (title text, raster lo);

CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
    FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);

Para cada columna que contendrá referencias únicas a objetos grandes, crea un disparador BEFORE UPDATE OR DELETE y proporciona el nombre de la columna como único argumento del disparador. También puedes restringir el disparador para que solo se ejecute al actualizar la columna usando BEFORE UPDATE OF column_name. Si necesitas múltiples columnas lo en la misma tabla, crea un disparador independiente para cada una, recordando dar un nombre diferente a cada disparador en la misma tabla.

F.21.3. Limitaciones #

  • Eliminar una tabla (DROP TABLE) seguirá dejando huérfanos a los objetos que contiene, ya que el disparador no se ejecuta. Puedes evitar esto precediendo el DROP TABLE con DELETE FROM table.

    TRUNCATE presenta el mismo peligro.

    Si ya tienes, o sospechas que tienes, objetos grandes huérfanos, consulta el módulo vacuumlo para que te ayude a limpiarlos. Es una buena idea ejecutar vacuumlo ocasionalmente como respaldo al disparador lo_manage.

  • Algunas interfaces (frontends) pueden crear sus propias tablas y no crearán los disparadores asociados. Además, es posible que los usuarios no recuerden (o no sepan) crear los disparadores.

F.21.4. Autor #

Peter Mount