2016-10-25 8 views
0

У меня есть таблица в Postgres 9.4, и мне нужно сделать следующее:Postgres сделать цепочку записей в одной таблице

Когда новая вставленная запись приходит, мне нужно найти предыдущие записи с заданными параметрами и назначить его «next_message 'значение столбца для вновь созданной записи. Поэтому я хочу, чтобы в каждой записи была ссылка на следующую с заданным фильтром, например «session_id». Итак, если session_id = 5, все записи с seeion_id = 5 должны ссылаться на следующий. Я создал триггер, который выбирает предыдущую запись и устанавливает это поле. Но это плохо, и он не будет работать в загруженной таблице db. Как это сделать?

Это мой триггер:

CREATE OR REPLACE FUNCTION "public"."messages_compute_next_message"() RETURNS trigger 
    VOLATILE 
AS $dbvis$ 
DECLARE previous_session_message integer; 

BEGIN 
/*NEW.next_message_id=NEW.id;*/ 
update message set next_message_id=NEW.id where id=(select max(c.id) from message c where c.session_id=NEW.session_id and c.id<>NEW.id); 
RETURN NEW; 
END 
$dbvis$ LANGUAGE plpgsql 

Если я отправляю записи слишком часто, я получаю много пустых значений в полях next_message_id. И это логично, иначе мне придется блокировать всю таблицу на каждой вставке. Как это сделать в postgres?

ответ

1

Я бы сказал, забудьте о next_message_id.

Как выглядит ваш триггер, мне кажется, что сообщения упорядочены id в течение одного сеанса.

Так что, если вам нужно предыдущее сообщение для сообщения с id 42, вы можете найти его с

SELECT max(prev.id) 
FROM message prev JOIN message curr 
    ON prev.session_id = curr.session_id 
     AND prev.id < curr.id 
WHERE curr.id = 42; 

Установка правильных индексов будет ускорить этот процесс значительно.

Предполагаю, что уже есть индекс на id; может быть, второй индекс ON (session_id, id) поможет.

+0

Спасибо! Это помогло! – avalon