F.28. lo — управление большими объектами#
F.28. lo — управление большими объектами #
Модуль lo
обеспечивает поддержку управления большими объектами (также называемыми LO или BLOB). Это включает в себя тип данных lo
и триггер lo_manage
.
Этот модуль считается "доверенным", то есть его можно установить
недоступным пользователям, у которых есть привилегия CREATE
в текущей базе данных.
F.28.1. Обоснование #
Одной из проблем с драйвером JDBC (и это также относится к драйверу ODBC) является то, что спецификация предполагает, что ссылки на BLOB (бинарные большие объекты) хранятся внутри таблицы, и если запись изменяется, связанный BLOB удаляется из базы данных.
Как сейчас работает Tantor SE-1C, такого не происходит. Большие объекты рассматриваются как отдельные объекты; запись в таблице может ссылаться на большой объект по OID, но может быть несколько записей в таблице, ссылающихся на один и тот же OID большого объекта, поэтому система не удаляет большой объект только потому, что вы изменяете или удаляете одну такую запись.
Теперь это подходит для специфичных для Tantor SE-1C приложений, но стандартный код, использующий JDBC или ODBC, не будет удалять объекты, что приведет к появлению сиротских объектов — объектов, на которые нет ссылок, и которые просто занимают место на диске.
Модуль lo
позволяет исправить эту проблему, присоединяя триггер к таблицам, содержащим столбцы с ссылками на LO. Триггер в основном выполняет функцию lo_unlink
при удалении или изменении значения, ссылающегося на большой объект. При использовании этого триггера вы предполагаете, что существует только одна базовая ссылка на любой большой объект, на который ссылаются в столбце, управляемом триггером!
Модуль также предоставляет тип данных lo
, который на самом деле является просто доменом над типом oid
. Это полезно для разграничения столбцов базы данных, которые содержат ссылки на большие объекты, от тех, которые являются OID других объектов. Для использования триггера не обязательно использовать тип lo
, но может быть удобно использовать его для отслеживания столбцов в базе данных, представляющих большие объекты, которыми вы управляете с помощью триггера. Также есть слух, что драйвер ODBC путается, если не использовать тип lo
для столбцов BLOB.
F.28.2. Как использовать это #
Вот простой пример использования:
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);
Для каждого столбца, который будет содержать уникальные ссылки на большие объекты, создать триггер BEFORE UPDATE OR DELETE
и указать имя столбца в качестве единственного аргумента триггера. Также можно ограничить выполнение триггера только при обновлении столбца, используя BEFORE UPDATE OF
column_name
. Если вам нужно несколько столбцов lo
в одной таблице, необходимо создать отдельный триггер для каждого из них, не забывая давать каждому триггеру на одной таблице разное имя.
F.28.3. Ограничения #
Удаление таблицы все равно оставит сиротливые объекты, так как триггер не будет выполнен. Вы можете избежать этого, предварив
DROP TABLE
командойDELETE FROM
.table
TRUNCATE
имеет ту же опасность.Если у вас уже есть или вы подозреваете, что у вас есть потерянные большие объекты, обратитесь к модулю vacuumlo, чтобы помочь вам их очистить. Рекомендуется периодическое запускание приложения vacuumlo в качестве дополнительной защиты для триггера
lo_manage
.Некоторые фронтенды могут создавать свои собственные таблицы и не создавать соответствующие триггеры. Кроме того, пользователи могут не помнить (или не знать), что нужно создавать триггеры.
F.28.4. Автор #
Peter Mount <peter@retep.org.uk>