Ситуация
У меня есть база данных в PostgreSQL 9.5, используемая для хранения местоположения объектов по времени.
У меня есть основная таблица с именем «позиция» со столбцами (только релевантными):
position_id
position_timestamp
object_id
Он разбит на 100 дочерних таблиц по object_id с условием:
CREATE TABLE position_object_id_00
( CHECK object_id%100 = 0 )
INHERITS ( position );
И так далее для остальных детей. Я разделил с отношением модуля, чтобы равномерно распределить объекты. Каждый дочерний элемент индексируется по position_id and object_id
(два разных индекса).
Триггер для перенаправления вставок на дочерние элементы:
CREATE TRIGGER insert_position_trigger
BEFORE INSERT ON position
FOR EACH ROW EXECUTE PROCEDURE insert_position();
И процедура insert_position()
ищет правильную дочернюю таблицу для вставки данных, вставляет ее и возвращает НОВЫЙ объект:
CREATE OR REPLACE FUNCTION insert_position() RETURNS TRIGGER AS $insert_position$
DECLARE
BEGIN
--Look for child table
[...]
--Insert data in right child table
[...]
RETURN NEW;
END;
$insert_position$ LANGUAGE plpgsql;
У меня есть сводная таблица object_last_known_position
с теми же столбцами, которые обновляются с помощью триггера:
CREATE TRIGGER update_object_last_known_position
AFTER INSERT OR UPDATE ON position
FOR EACH ROW
EXECUTE PROCEDURE update_object_last_known_position();
Процедура update_object_last_known_position()
в основном проверяет, является ли position_timestamp
более новым, затем удаляет старую запись и создает новую запись с данными, переданными в запросе INSERT или UPDATE (NEW).
Проблема
Таким образом, эти два триггера реагируют на одно и то же событие: вставка в позицию, один до, другой после Возврат нового для insert_position()
позволяет мне использовать NEW в триггере update_object_last_known_position()
, а это абсолютно необходимо. Но при этом он также вставляет данные о позиции главной таблицы. Итак, мои данные теперь дублируются.
Пробовал ставить два триггера раньше, они оба выполняются при вставке данных если я так разрешу, но если я уберу "return new" из процедуры insert_position()
, update_object_last_known_position()
не выполняется.
Я застрял в этой проблеме, и я не нашел способа выполнить оба этих триггера без заполнения позиции главной таблицы при вставке данных.
Так что, если есть идеи, буду очень признателен :)
Спасибо за помощь!
ИЗМЕНИТЬ
Решение
Благодаря ответу
Я «объединил» два своих триггера: insert_position()
теперь вызывает update_object_last_known_position
напрямую. Для этого я изменил update_object_last_known_position
на хранимую процедуру с параметром. Параметр - это идентификатор только что созданной позиции insert_position()
, поэтому я могу найти ее и получить информацию. (Вызов update_object_last_known_position
внутри другого триггера означает, что мы больше не можем использовать NEW
) И, очевидно, тип возвращаемого значения для insert_position()
теперь NULL
, и все работает нормально :)
update_object_last_known_position()
, а также вставляете (чтобы запустить триггер). Не могли бы вы просто не вставить строку вupdate_object_last_known_position()
- person Philip Couling   schedule 25.08.2016update_object_last_known_position()
, а сinsert_position()
. Поскольку это триггер перед возвратом NEW, я думаю, он не останавливает INSERT. И мне нужно вставить строку вobject_last_known_position
, это часть дизайна: мне нужно сохранить последнюю позицию, чтобы иметь лучшую производительность при запросе. - person Miwauke   schedule 25.08.2016