F.26. lo#

F.26. lo

F.26. lo

Модуль lo обеспечивает поддержку управления большими объектами (также называемыми LO или BLOB). Это включает в себя тип данных lo и триггер lo_manage.

Этот модуль считается "доверенным", то есть его можно установить недоступным пользователям, у которых есть привилегия CREATE в текущей базе данных.

F.26.1. Обоснование

Одной из проблем с драйвером JDBC (и это также относится к драйверу ODBC) является то, что спецификация предполагает, что ссылки на BLOB (бинарные большие объекты) хранятся внутри таблицы, и если запись изменяется, связанный BLOB удаляется из базы данных.

Как сейчас работает Tantor SE, такого не происходит. Большие объекты рассматриваются как отдельные объекты; запись в таблице может ссылаться на большой объект по OID, но может быть несколько записей в таблице, ссылающихся на один и тот же OID большого объекта, поэтому система не удаляет большой объект только потому, что вы изменяете или удаляете одну такую запись.

Теперь это подходит для специфичных для Tantor SE приложений, но стандартный код, использующий JDBC или ODBC, не будет удалять объекты, что приведет к появлению сиротских объектов — объектов, на которые нет ссылок, и которые просто занимают место на диске.

Модуль lo позволяет исправить эту проблему, присоединяя триггер к таблицам, содержащим столбцы с ссылками на LO. Триггер в основном выполняет функцию lo_unlink при удалении или изменении значения, ссылающегося на большой объект. При использовании этого триггера вы предполагаете, что существует только одна базовая ссылка на любой большой объект, на который ссылаются в столбце, управляемом триггером!

Модуль также предоставляет тип данных lo, который на самом деле является просто доменом над типом oid. Это полезно для разграничения столбцов базы данных, которые содержат ссылки на большие объекты, от тех, которые являются OID других объектов. Для использования триггера не обязательно использовать тип lo, но может быть удобно использовать его для отслеживания столбцов в базе данных, представляющих большие объекты, которыми вы управляете с помощью триггера. Также есть слух, что драйвер ODBC путается, если не использовать тип lo для столбцов BLOB.

F.26.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.26.3. Ограничения

  • Удаление таблицы все равно оставит сиротливые объекты, так как триггер не будет выполнен. Вы можете избежать этого, предварив DROP TABLE командой DELETE FROM table.

    TRUNCATE имеет ту же опасность.

    Если у вас уже есть или вы подозреваете, что у вас есть потерянные большие объекты, обратитесь к модулю vacuumlo, чтобы помочь вам их очистить. Рекомендуется периодическое запускание приложения vacuumlo в качестве дополнительной защиты для триггера lo_manage.

  • Некоторые фронтенды могут создавать свои собственные таблицы и не создавать соответствующие триггеры. Кроме того, пользователи могут не помнить (или не знать), что нужно создавать триггеры.

F.26.4. Автор

Peter Mount