Есть ли способ установить время «истечения», по истечении которого запись данных автоматически удаляется в PostgreSQL?

110

Есть ли способ установить какое-то время «истечения» для записей данных в PostgreSQL ? Я думаю о чем-то эквивалентном EXPIRERedis .

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

Я пытаюсь выяснить, есть ли в PostgreSQL какая-либо встроенная функция, которая обеспечивала бы такую ​​функциональность, или имеет смысл запросить такую ​​функцию для будущих выпусков.

Pensierinmusica
источник
1
В списке рассылки postgresql
vonPetrushev

Ответы:

108

Нет встроенной функции истечения срока действия, но если ваша цель - автоматически истечь поля и иметь логику, содержащуюся в вашей базе данных (и, следовательно, не иметь внешней зависимости, такой как задание cron), вы всегда можете написать триггер. Ниже приведен пример триггера, который удаляет строки из таблицы с отметкой времени старше 1 минуты. Он выполняется всякий раз, когда в ту же таблицу вставляется новая строка. Очевидно, вы можете настроить триггер на выполнение при других условиях и для различных дат истечения срока, если это необходимо. За основу я взял следующий веб-сайт: http://www.the-art-of-web.com/sql/trigger-delete-old/

CREATE TABLE expire_table (
    timestamp timestamp NOT NULL DEFAULT NOW(),
    name TEXT NOT NULL
);

INSERT INTO expire_table (name) VALUES ('a');
INSERT INTO expire_table (name) VALUES ('b');
INSERT INTO expire_table (name) VALUES ('c');

select * from expire_table;
         timestamp          | name 
----------------------------+------
 2014-09-26 15:33:43.243356 | a
 2014-09-26 15:33:45.222202 | b
 2014-09-26 15:33:47.347131 | c
(3 rows)

CREATE FUNCTION expire_table_delete_old_rows() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
BEGIN
  DELETE FROM expire_table WHERE timestamp < NOW() - INTERVAL '1 minute';
  RETURN NEW;
END;
$$;

CREATE TRIGGER expire_table_delete_old_rows_trigger
    AFTER INSERT ON expire_table
    EXECUTE PROCEDURE expire_table_delete_old_rows();

INSERT INTO expire_table (name) VALUES ('d');

select * from expire_table;
         timestamp          | name 
----------------------------+------
 2014-09-26 15:36:56.132596 | d
(1 row)
Бретт ДиДонато
источник
1
@caeus, вероятно, зависит от кеширования и индексации
Нимрод
44
-1. Имхо, триггеры - это не тот способ, которым вы должны иметь дело с отсутствующими функциями базы данных, потому что триггеры сложно тестировать, их сложно поддерживать и это просто заноза в заднице. Будьте честны и внедрите это в свое приложение. :)
Bastian Voigt
2
Согласитесь, я считаю, что проверять старые записи и удалять их на каждой вставке - действительно ужасное решение с точки зрения производительности. Не так уж и сложно настроить даже что-то вроде сценария задания CRON, для выполнения которого, например, требуется SQL.
zarkone
производительность должна быть довольно хорошей, если есть индекс времени истечения срока действия.
Jasen
3
+1 к решению Бретта. Для чего-то вроде сеансовой таблицы, где вы когда-либо хотели бы, чтобы у пользователя был только один сеанс, я думаю, что триггер для любого INSERT в сеансовую таблицу, чтобы убедиться, что каждый пользователь имеет только один сеанс, является совершенно допустимым вариантом использования. . Люди зацикливаются на том, что что-то «можно протестировать», поэтому они пишут более сложные решения (которые затем требуют тщательного тестирования), а не какую-то простую функцию, которая, как они могут быть уверены, не сломается.
Corysimmons
8

Нет. Такой функции нет.

Я не вижу, что он делает больше, чем (1) просто отметка времени с истекшим сроком действия или (2) отметка времени + cron-job / pgAgent.

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

Я ничего не вижу на pgxn , так что, по- видимому , на него пока не было большого спроса.

Ричард Хакстон
источник
3
Я знаю, что этот ответ старый, но ИМО это невероятно полезная функция, например: docs.mongodb.com/manual/core/index-ttl
Madbreaks
для добавления этой функции в postgresql потребуется много работы, например, для создания внешнего ключа потребуются другие правила ...
Jasen