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.
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.
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.
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.
Peter Mount <[email protected]>