• Аудит
  • Консалтинг
  • Миграция
    • Миграция с Oracle на PostgreSQL
    • Миграция 1С на PostgreSQL
  • Поддержка
  • Статьи и инструкции
Меню
  • Аудит
  • Консалтинг
  • Миграция
    • Миграция с Oracle на PostgreSQL
    • Миграция 1С на PostgreSQL
  • Поддержка
  • Статьи и инструкции

Управляющее поле

При работе с триггерами, особенно в случаях, когда на уровне триггеров производятся каскадные или перекрестные обновления, возникает потребность отключать или производить определенные действия в триггерах прямо на уровне запроса.

Далее я хотел написать (и уже написал, но потом убрал) множество примеров, но так как они захватывают достаточно много сопутсвующих вещей и задач которые тоже потребуется разъяснять, что в конце я решил, что имеет смысл сгруппировать примеры по видам задач и сделать отдельные разборы, здесь же мы просто опишем основные правила и задачи управляющего поля.

Задачи управляющего поля

Обычное у меня название этого поля — _trigger_off. Изначально оно предназначалось для того, что бе когда производится INSERT или UPDATE, то если в запросе оно передается как TRUE, то в триггере происходил сразу возврат из процедуры с обнулением этого поля, то есть по сути триггерная функция вызывалась, но никаких действий не производила. В данный момент понятие этого поля трансформировалось в более широкое понятие, но название осталось прежним, так что связывать название этого поля с его значение в прямом смысле не имеет значения, вы можете его называть как вам удобно, я называю так, по привычке.

Тип поля — BOOLEAN. На самом деле, при условии что поле может быть NULL, то вариантов значений поля становится не 2 (TRUE, FALSE), а 4 (TRUE, FALSE, NULL, NOT NULL), это важно и вот почему:

  • Данное поле позволяет определить стоит ли исполнять основной код триггерной функции или нет (TRUE или FALSE);
  • Так же оно позволяет определить откуда был произведен запрос, из приложения или из соседнего триггера (NULL или NOT NULL);

В сухом остатке задачи управляющего поля можно определить таким образом: понять откуда пришел запрос и что с ним делать. И что бы на эти вопросы был однозначный ответ, требуется придерживаться определенных правил.

Правила управляющего поля

1. Поле в таблице ВСЕГДА сохранятся NULL

То есть, какое из значений поля не передавалось бы, в результате оно обязательно приводится к NULL. При чем, не зависимо от того, все ли триггера есть или только на определенные запросы, требуется ставить триггер-заглушку, которая сбросит значение поля в NULL. Для удобства я делаю одну общую хранимую процедуру:

CREATE FUNCTION "public"."flush_trigger_off" (
)
RETURNS TRIGGER AS
$body$
BEGIN
    NEW._trigger_off := NULL;
    RETURN NEW;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE;

А после создания таблицы в которой присутсвует управляющее поле, сразу создаю для нее триггер:

CREATE TRIGGER flush_control_field
    BEFORE INSERT OR UPDATE 
    ON [table_name] FOR EACH ROW 
    EXECUTE PROCEDURE "public"."flush_trigger_off"();

И тогда не надо будет переживать по поводу того, что триггеры еще не написаны, но данные уже льются, и мало ли.

Соответсвенно при соблюдении данного правила, значение данного поля по-умочанию будет NULL, как в новой (NEW) так и в старой (OLD) строке.

Так же это правило, как следствие экономит место, так так поле всегда NULL, то места физически оно не занимает, только виртуально в разметке строк.

2. Данное поле НЕ должно использоваться внешним приложением

Так как данное поле является внутренним, то приложению, которое использует базу данных совершенно не обязательно о нем знать, а тем более использовать. Тут все просто, если приложение штатно использует данное поле, значит вы не справились с задачами целостности данных на уровне базы данных, и стоит пересмотреть всю логику.

Единственным исключением, когда данное поле можно использовать в запросах вне триггеров — это для восстановления целостности данных, что периодически бывает при достаточно большой и сложной структуре и повсеместном использовании денормализации. Но это не является штатными задачами приложения, так что правило здесь не работает. Но стоит иметь ввиду, что если вы используете это поле в «ручных» запросах, то контроль целостности данных и связей лежит исключительно на вас.

По большому счету значение поля NULL говорит о том, что триггер должен сам озаботится о целостности данных и решить что и как делать.

3. Данное поле должно ВСЕГДА использоваться во внутренних запросах

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

Здесь, конечно стоит разделять запросы обеспечения целостности данных и связей от обычных запросов, которые не влияют на целостность. Поэтому устанавливать принудительно это поле отличное от нуля для абсолютно всех подзапросов на уровне базы данных — не имеет смысла.

В итоге

Использование подобного поля позволяет контролировать точки входа запросов и принимать соответсвующие решения.

Рубрики
  • Базы данных
    • PostgreSQL
    • Деревья
  • Без рубрики
  • Веб
    • Nginx
  • Операционные системы
    • Linux
Метки
ACL Adjacency List Contrib DevOps Extensions GRANT Linux ltree Materialized Path Nested Sets nginx ngx_http_dav_module ngx_http_image_filter_module ngx_http_map_module ngx_http_proxy_module ngx_http_random_index_module ngx_http_secure_link_module pg_hba.conf PostgreSQL privileges REVOKE Trees Ubuntu Web ZFS Деревья Индекс Миграция Оптимизация запросов триггеры

КОНСАЛТИНГ 
ПО POSTGRESQL

Консалтинг — 
это когда мы сами выполняем работу

ПОДРОБНЕЕ

ЕЩЕ СТАТЬИ ПО ДАННОЙ ТЕМЕ

PostgreSQL. Миграция. Как начать

Вот проснулись вы как-то утром и решили начать новую жизнь вместе с базой данных PostgreSQL оставив другие за бортом. Но с чего начать? Как «подкатить» и не быть отвергнутым? А ведь вы уже не молоды и «с прицепом»: с данными, нагрузкой и бизнес-логикой.
Так как в данный момент тема миграций в тренде, не могу пройти мимо и не поделится своим опытом подобных мероприятий. Данная задача не самая простая, так как требует подмены одной из фундаментальных технологий проекта — хранилище данных.

Читать далее »

PostgreSQL. Хочешь похудеть? Cпроси меня как.

Недавно попросили поднять копию одного проекта для тестов, ну и соответственно потянуть базу данных как есть из боя (pg_basebackup). Выяснилось, что физический размер базы составил 505 GB, что само по себе слегка удивило, не то, чтобы данных там было мало. Много, но не настолько.

Читать далее »

PostgreSQL ACL Object

В предыдущей статье мы рассматривали вопросы подключения и глобальных привилегий пользователей сервера PostgreSQL. Будем считать что головную боль админов в виде pg_hba.conf мы прошли, переходим к следующей.
DBA против Разработчиков, DML против DDL. Сразу хочу сказать, что мое мнение: привилегии DDL разработчику не нужны, несмотря на то, что я сам разработчик.

Читать далее »

Поддержка

Поддержка — это когда у нас возникает техническая
проблема с существующей системой,
и вам необходимо некоторое руководство

ПОДРОБНЕЕ

Postgres.men

  • Аудит
  • Консалтинг
  • Поддержка
  • Статьи и инструкции

Миграция

  • Миграция с Oracle на PostgreSQL
  • Миграция 1С на PostgreSQL

Мы в соцсетях

  • Вконтакте

© Postgres.Men by Taktive Ltd, 2022. Не является публичной офертой.