Existe uma maneira de definir um tempo de “expiração”, após o qual uma entrada de dados é excluída automaticamente no PostgreSQL?


107

Existe alguma maneira de definir algum tipo de tempo de "expiração" nas entradas de dados no PostgreSQL ? Estou pensando em algo equivalente ao EXPIRERedis .

Não estou procurando armazenar um carimbo de data / hora e, em seguida, codificar manualmente algum tipo de cron job para verificar quais entradas expiraram.

Estou tentando descobrir se existe algum recurso nativo no PostgreSQL que forneça esse tipo de funcionalidade, ou se faria sentido solicitar esse recurso para versões futuras.


1
Houve uma discussão na lista de discussão do postgresql postgresql.org/message-id/…
vonPetrushev

Respostas:


105

Não há nenhum recurso de expiração embutido, mas se seu objetivo é expirar campos automaticamente e ter a lógica contida em seu banco de dados (e, portanto, nenhuma dependência externa como um cron job), então você sempre pode escrever um gatilho. Abaixo está um exemplo de um gatilho que exclui linhas de uma tabela com um carimbo de data / hora com mais de 1 minuto. Ele é executado sempre que uma nova linha é inserida na mesma tabela. Obviamente, você pode definir o gatilho para executar em outras condições e para várias datas de expiração, conforme necessário. Usei o seguinte site como base para isso: 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 provavelmente depende de cache e indexação
Nimrod,

39
-1. Imho, triggers não são a maneira que você deve lidar com recursos de banco de dados ausentes, porque triggers são difíceis de testar, difíceis de manter e apenas um pé no saco. Seja honesto e implemente-o em seu aplicativo. :)
Bastian Voigt

2
Concordo, acho que verificar registros antigos e excluí-los de cada inserção é uma solução realmente terrível em termos de desempenho. Não é tão difícil configurar até mesmo algo como script de tarefa CRON que executa requer SQL, por exemplo.
zarkone

o desempenho deve ser razoavelmente bom se houver um índice de tempo de expiração.
Jasen

2
+1 para a solução de Brett. Para algo como uma tabela de sessão onde você quer que um usuário tenha apenas uma sessão, eu acho que um gatilho em qualquer INSERT para a tabela de sessão, para garantir que cada usuário tenha apenas uma sessão, é um caso de uso perfeitamente válido . As pessoas ficam obcecadas se algo é "testável", então escrevem soluções mais complexas (que então precisam de testes pesados) em vez de alguma função simples que podem ter certeza de que não quebrará.
corysimmons

8

Não. Esse recurso não existe.

Não consigo ver o que ele faz mais do que (1) apenas um carimbo de data / hora "expirado" ou (2) carimbo de data / hora + cron-job / pgAgent.

Não parece um recurso geral que seria adicionado ao núcleo. Você poderia simplesmente codificar uma extensão para lidar com esse tipo de coisa, com um tick chamado de um cron-job ou talvez um processo de trabalho em segundo plano .

Não vejo nada no pgxn , então presumivelmente ainda não houve muita demanda por ele.


3
Eu sei que esta resposta é antiga, mas IMO é um recurso extremamente útil, por exemplo: docs.mongodb.com/manual/core/index-ttl
Madbreaks

exigiria muito trabalho adicionar esse recurso ao postgresql, por exemplo, a criação de chave estrangeira precisaria de regras diferentes ...
Jasen
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.