C'è un modo per impostare un tempo di "scadenza", dopo il quale una voce di dati viene automaticamente cancellata in PostgreSQL?


108

C'è un modo per impostare una sorta di tempo di "scadenza" per le voci di dati in PostgreSQL ? Sto pensando a qualcosa di equivalente a EXPIRERedis .

Non sto cercando di memorizzare un timestamp e quindi codificare manualmente una sorta di cron job per verificare quali voci sono scadute.

Sto cercando di scoprire se c'è qualche caratteristica nativa in PostgreSQL che fornirebbe questo tipo di funzionalità, o se avrebbe senso richiedere tale funzionalità per le versioni future.


1
C'è stata una discussione sulla mailing list postgresql postgresql.org/message-id/…
vonPetrushev il

Risposte:


106

Non esiste una funzione di scadenza incorporata, ma se il tuo obiettivo è far scadere automaticamente i campi e avere la logica contenuta nel tuo database (e quindi nessuna dipendenza esterna come un cron job), puoi sempre scrivere un trigger. Di seguito è riportato un esempio di un trigger che elimina le righe da una tabella con un timestamp precedente a 1 minuto. Viene eseguito ogni volta che una nuova riga viene inserita nella stessa tabella. È ovviamente possibile impostare il trigger per l'esecuzione in altre condizioni e per varie date di scadenza secondo necessità. Ho utilizzato il seguente sito Web come base per questo: 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 probabilmente dipende dalla memorizzazione nella cache e dall'indicizzazione
Nimrod

39
-1. Imho, i trigger non sono il modo in cui dovresti gestire le funzionalità del database mancanti, perché i trigger sono difficili da testare, difficili da mantenere e solo un rompicoglioni. Sii onesto e implementalo nella tua applicazione. :)
Bastian Voigt

2
D'accordo, penso che controllare i vecchi record ed eliminarli su ogni inserto sia una soluzione davvero terribile in termini di prestazioni. Ad esempio, non è così difficile impostare anche qualcosa come lo script di lavoro CRON che viene eseguito richiede SQL.
zarkone

la prestazione dovrebbe essere abbastanza buona se c'è un indice sul tempo di scadenza.
Jasen

2
+1 alla soluzione di Brett. Per qualcosa come una tabella di sessione in cui vorresti che un utente abbia una singola sessione, penso che un trigger su qualsiasi INSERT nella tabella di sessione, per assicurarti che ogni utente abbia solo una sessione, è un caso d'uso perfettamente valido . Le persone sono ossessionate dal fatto che qualcosa sia "testabile", quindi scrivono soluzioni più complesse (che poi necessitano di test pesanti) piuttosto che qualche semplice funzione che possono essere certi che non si interrompano.
corysimmons

8

No. Non esiste una funzione del genere.

Non riesco a vedere cosa fa più di (1) solo un timestamp "scaduto" o (2) timestamp + cron-job / pgAgent.

Non sembra una caratteristica generale che verrebbe aggiunta al nucleo. Potresti semplicemente codificare un'estensione per gestire questo genere di cose, con un segno di spunta chiamato da un cron-job o forse un processo di lavoro in background .

Non vedo nulla su pgxn , quindi presumibilmente non c'è stata ancora molta richiesta per questo.


3
So che questa risposta è vecchia ma IMO è una funzionalità incredibilmente utile, ad esempio: docs.mongodb.com/manual/core/index-ttl
Madbreaks

richiederebbe molto lavoro per aggiungere questa funzione a postgresql, ad esempio, la creazione di una chiave esterna richiederebbe regole diverse ...
Jasen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.