×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

5.4.7. Правила и триггеры

Многие задачи, реализуемые с помощью триггеров, могут быть также решены через Digital Q.DataBase систему правил. К числу задач, которые невозможно реализовать с помощью правил, относятся некоторые виды ограничений, в частности внешние ключи. Можно создать условное правило, которое переписывает команду в NOTHING если значение столбца отсутствует в другой таблице. Однако в этом случае данные будут просто отброшены, что не является оптимальным решением. Если требуется проверка значений на корректность и при обнаружении недопустимого значения должно быть сформировано сообщение об ошибке, эту операцию должен выполнять триггер.

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

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

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

CREATE TABLE computer (
    hostname        text,    -- индексировано
    manufacturer    text     -- индексировано
);

CREATE TABLE software (
    software        text,    -- индексировано
    hostname        text     -- индексировано
);

Обе таблицы содержат многие тысячи строк, а индексы по полю hostname являются уникальными. Правило или триггер должны реализовать ограничение, удаляющее строки из таблицы software , которые ссылаются на удаленный компьютер. Триггер будет использовать следующую команду:

DELETE FROM software WHERE hostname = $1;

Поскольку триггер вызывается для каждой отдельной строки, удаляемой из таблицы computer, он может подготовить и сохранить план для этой команды, передавая hostname значение через параметр. Это правило записывается следующим образом:

CREATE RULE computer_del AS ON DELETE TO computer
    DO DELETE FROM software WHERE hostname = OLD.hostname;

Теперь рассмотрим различные типы операций удаления. В случае выполнения команды:

DELETE FROM computer WHERE hostname = 'mypc.local.net';

таблица computer сканируется по индексу (быстро), и команда, инициируемая триггером, также будет использовать сканирование индекса (также быстро). Дополнительная команда, порождённая правилом, будет иметь вид:

DELETE FROM software WHERE computer.hostname = 'mypc.local.net'
                       AND software.hostname = computer.hostname;

Поскольку настроены соответствующие индексы, планировщик создаст следующий план:

Nestloop
  ->  сканирование индекса с использованием comp_hostidx по таблице computer
  ->  сканирование индекса с использованием soft_hostidx по таблице software

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

При следующем удалении мы хотим удалить все 2000 компьютеров, у которых hostname начинается с old. Существуют две возможные команды для этого. Первая из них:

DELETE FROM computer WHERE hostname >= 'old'
                       AND hostname <  'ole'

Команда, добавленная правилом, будет иметь вид:

DELETE FROM software WHERE computer.hostname >= 'old' AND computer.hostname < 'ole'
                       AND software.hostname = computer.hostname;

с планом

Hash Join
  ->  Seq Scan on software
  ->  Hash
    ->  сканирование индекса с использованием comp_hostidx для computer

Другая возможная команда:

DELETE FROM computer WHERE hostname ~ '^old';

что приводит к следующему плану выполнения для команды, добавленной правилом:

Nestloop
  ->  сканирование индекса с использованием comp_hostidx по таблице computer
  ->  сканирование индекса с использованием soft_hostidx по таблице software

Это показывает, что планировщик не понимает, что выражение условия для hostname в computer также может быть использовано для сканирования индекса по software при наличии нескольких выражений условий, объединенных с помощью AND, как это происходит в версии команды с регулярным выражением. Триггер будет вызван один раз для каждого из 2000 старых компьютеров, подлежащих удалению, что приведет к одному сканированию индекса по computer и 2000 сканирований индекса по software. Реализация правила выполнит это с помощью двух команд, использующих индексы. И от общего размера таблицы зависит, software окажется ли правило быстрее в ситуации с последовательным сканированием. 2000 выполнений команд триггера через менеджер SPI занимают определенное время, даже если все блоки индекса вскоре окажутся в кэше.

Последняя команда, которую мы рассмотрим:

DELETE FROM computer WHERE manufacturer = 'bim';

Это также может привести к удалению множества строк из computer. Таким образом, триггер снова запустит множество команд через исполнитель. Команда, сгенерированная правилом, будет следующей:

DELETE FROM software WHERE computer.manufacturer = 'bim'
                       AND software.hostname = computer.hostname;

Планом для этой команды снова будет вложенный цикл по двум сканированиям индекса, но с использованием другого индекса по computer:

Nestloop
  ->  сканирование индекса с использованием comp_manufidx по таблице computer
  ->  сканирование индекса с использованием soft_hostidx по таблице software

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

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

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению