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

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

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

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


person Pensierinmusica    schedule 25.09.2014    source источник
comment
В списке рассылки postgresql было обсуждение postgresql.org/message-id/   -  person vonPetrushev    schedule 30.06.2015


Ответы (2)


Встроенной функции истечения срока действия нет, но если вашей целью является автоматическое истечение срока действия полей и наличие логики, содержащейся в вашей базе данных (и, следовательно, отсутствие внешней зависимости, такой как задание 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)
person Brett DiDonato    schedule 26.09.2014
comment
@caeus, вероятно, зависит от кэширования и индексации - person Nimrod; 21.03.2017
comment
-1. Имхо, триггеры - это не тот способ, которым вы должны справляться с отсутствующими функциями базы данных, потому что триггеры трудно тестировать, сложно поддерживать и просто заноза в заднице. Будьте честны и реализуйте это в своем приложении. :) - person Bastian Voigt; 20.04.2017
comment
Согласитесь, я считаю, что проверять старые записи и удалять их при каждой вставке действительно ужасное решение с точки зрения производительности. Не так сложно настроить даже что-то вроде сценария задания CRON, который, например, выполняет запрос SQL. - person zarkone; 25.02.2018
comment
производительность должна быть достаточно хорошей, если есть индекс времени истечения срока действия. - person Jasen; 22.02.2020
comment
Это должно быть либо управляемым уровнем приложения, либо запускаться как отдельное задание SQL, запрос данных также должен использовать предложение where для ограничения, поскольку это бизнес-логика, и следует четко указать, что информация находится в пределах ограничения. - person Marco; 04.05.2020
comment
+1 к решению Бретта. Для чего-то вроде таблицы сеансов, где вы хотите, чтобы у пользователя был только один сеанс, я думаю, что триггер на любой INSERT в таблицу сеансов, чтобы убедиться, что у каждого пользователя есть только один сеанс, является совершенно допустимым вариантом использования. . Люди зацикливаются на том, можно ли что-то протестировать, поэтому они пишут более сложные решения (которые затем требуют серьезного тестирования), а не какую-то простую функцию, которая, как они могут быть уверены, не сломается. - person corysimmons; 10.05.2020

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

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

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

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

person Richard Huxton    schedule 25.09.2014
comment
Я знаю, что этот ответ устарел, но IMO это невероятно полезная функция, например: docs.mongodb .com/manual/core/index-ttl - person Madbreaks; 17.01.2020
comment
для добавления этой функции в postgresql потребуется много работы, например, для создания внешнего ключа потребуются другие правила... - person Jasen; 22.02.2020