Gibt es eine Möglichkeit, eine Ablaufzeit festzulegen, nach der eine Dateneingabe in PostgreSQL automatisch gelöscht wird?

105

Gibt es eine Möglichkeit, eine Art "Ablaufzeit" für Dateneingaben in festzulegen? PostgreSQL festzulegen ? Ich denke an etwas, das EXPIRERedis entspricht .

Ich möchte keinen Zeitstempel speichern und dann manuell eine Art Cron- Job codieren, um zu überprüfen, welche Einträge abgelaufen sind.

Ich versuche herauszufinden, ob es in PostgreSQL eine native Funktion gibt, die diese Art von Funktionalität bietet, oder ob es sinnvoll wäre, eine solche Funktion für zukünftige Versionen anzufordern.

Pensierinmusica
quelle
1
Es gab Diskussionen auf der Postgresql-Mailingliste postgresql.org/message-id/…
vonPetrushev

Antworten:

105

Es gibt keine integrierte Ablauffunktion. Wenn Sie jedoch Felder automatisch ablaufen lassen und die Logik in Ihrer Datenbank enthalten möchten (und somit keine externe Abhängigkeit wie bei einem Cron-Job), können Sie jederzeit einen Trigger schreiben. Unten finden Sie ein Beispiel für einen Trigger, der Zeilen aus einer Tabelle löscht, deren Zeitstempel älter als 1 Minute ist. Es wird immer dann ausgeführt, wenn eine neue Zeile in dieselbe Tabelle eingefügt wird. Sie können den Auslöser natürlich so einstellen, dass er unter anderen Bedingungen und bei Bedarf für verschiedene Ablaufdaten ausgeführt wird. Ich habe die folgende Website als Grundlage dafür verwendet: 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)
Brett DiDonato
quelle
1
@ Caeus hängt wahrscheinlich von Caching und Indizierung ab
Nimrod
38
-1. Imho, Trigger sind nicht die Art und Weise, wie Sie mit fehlenden Datenbankfunktionen umgehen sollten, da Trigger schwer zu testen, schwer zu warten und nur nervig sind. Seien Sie ehrlich und implementieren Sie es in Ihrer Anwendung. :)
Bastian Voigt
2
Stimmen Sie zu, ich denke, dass das Überprüfen alter Datensätze und das Löschen auf jeder Beilage eine wirklich schreckliche Lösung in Bezug auf die Leistung ist. Es ist nicht so schwer, auch nur ein CRON-Jobskript einzurichten, für das beispielsweise SQL ausgeführt wird.
Zarkone
Die Leistung sollte ziemlich gut sein, wenn es einen Index für die Ablaufzeit gibt.
Jasen
2
+1 zu Bretts Lösung. Für so etwas wie eine Sitzungstabelle, in der ein Benutzer immer nur eine einzige Sitzung haben soll, ist ein Auslöser für jedes EINFÜGEN in die Sitzungstabelle, um sicherzustellen, dass jeder Benutzer nur eine Sitzung hat, ein absolut gültiger Anwendungsfall . Die Leute sind besessen davon, ob etwas "testbar" ist, und schreiben daher komplexere Lösungen (die dann umfangreiche Tests erfordern ) anstatt einer einfachen Funktion, von der sie sicher sein können, dass sie nicht kaputt geht.
Corysimmons
8

Nein, es gibt keine solche Funktion.

Ich kann nicht sehen, was es mehr tut als entweder (1) nur ein "abgelaufener" Zeitstempel oder (2) Zeitstempel + Cron-Job / pgAgent.

Es klingt nicht nach einer allgemeinen Funktion, die dem Kern hinzugefügt wird. Sie können ganz einfach eine Erweiterung codieren , um diese Art von Dingen zu handhaben, entweder mit einem Häkchen, das von einem Cron-Job oder einem Hintergrund-Worker- Prozess aufgerufen wird.

Ich sehe nichts auf pgxn , also gab es vermutlich noch keine große Nachfrage danach.

Richard Huxton
quelle
3
Ich weiß, dass diese Antwort alt ist, aber IMO ist sie eine unglaublich nützliche Funktion, zB: docs.mongodb.com/manual/core/index-ttl
Madbreaks
Es würde viel Arbeit erfordern, um diese Funktion zu postgresql hinzuzufügen, z. B. würde die Erstellung von Fremdschlüsseln andere Regeln erfordern ...
Jasen