Czy istnieje sposób na ustawienie czasu „wygaśnięcia”, po którym wpis danych jest automatycznie usuwany w PostgreSQL?

109

Czy istnieje sposób na ustawienie pewnego rodzaju czasu „wygaśnięcia” wpisów danych w PostgreSQL ? Myślę o czymś równoważnym z EXPIRERedis .

Nie chcę przechowywać sygnatury czasowej, a następnie ręcznie kodować jakieś zadanie cron, aby sprawdzić, które wpisy wygasły.

Próbuję się dowiedzieć, czy w PostgreSQL jest jakaś natywna funkcja, która zapewniłaby tego rodzaju funkcjonalność, czy też miałoby sens żądanie takiej funkcji w przyszłych wydaniach.

Pensierinmusica
źródło
1
Odbyła się

Odpowiedzi:

107

Nie ma wbudowanej funkcji wygaśnięcia, ale jeśli Twoim celem jest automatyczne wygasanie pól i posiadanie logiki zawartej w bazie danych (a zatem brak zewnętrznych zależności, takich jak zadanie cron), zawsze możesz napisać wyzwalacz. Poniżej znajduje się przykład reguły, która usuwa wiersze z tabeli z sygnaturą czasową starszą niż 1 minuta. Jest wykonywany za każdym razem, gdy nowy wiersz zostanie wstawiony do tej samej tabeli. Możesz oczywiście ustawić wyzwalacz tak, aby był wykonywany na innych warunkach i dla różnych dat wygaśnięcia, w zależności od potrzeb. Jako podstawę posłużyłem się następującą stroną internetową: 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
źródło
1
@caeus prawdopodobnie zależy od buforowania i indeksowania
Nimrod
40
-1. Imho, wyzwalacze nie są sposobem, w jaki powinieneś radzić sobie z brakującymi funkcjami bazy danych, ponieważ wyzwalacze są trudne do przetestowania, trudne do utrzymania i po prostu upierdliwe. Bądź uczciwy i zastosuj to w swojej aplikacji. :)
Bastian Voigt
2
Zgadzam się, myślę, że sprawdzanie starych rekordów i usuwanie ich na każdej wkładce to naprawdę straszne rozwiązanie pod względem wydajności. Nie jest trudno skonfigurować nawet coś takiego jak skrypt zadań CRON, który wykonuje na przykład język SQL.
zarkone
wydajność powinna być całkiem dobra, jeśli istnieje indeks czasu wygaśnięcia.
Jasen
2
+1 do rozwiązania Bretta. W przypadku czegoś takiego jak tabela sesji, w której chciałbyś, aby użytkownik miał tylko jedną sesję, myślę, że wyzwalacz na dowolnym INSERT do tabeli sesji, aby upewnić się, że każdy użytkownik ma tylko jedną sesję, jest całkowicie poprawnym przypadkiem użycia . Ludzie mają obsesję na punkcie tego, czy coś jest „testowalne”, więc piszą bardziej złożone rozwiązania (które następnie wymagają intensywnego testowania), zamiast prostych funkcji, co do których mogą być pewni, że się nie zepsują.
corysimmons
8

Nie. Nie ma takiej funkcji.

Nie widzę, co robi bardziej niż (1) tylko znacznik czasu „wygasły” lub (2) znacznik czasu + cron-job / pgAgent.

Nie brzmi to jak ogólna funkcja, która zostanie dodana do rdzenia. Mógłbyś po prostu zakodować rozszerzenie do obsługi tego rodzaju rzeczy, albo z tikiem wywoływanym z zadania cron, albo może z procesem roboczym w tle .

Nie widzę nic na pgxn , więc prawdopodobnie nie było jeszcze na to dużego zapotrzebowania.

Richarda Huxtona
źródło
3
Wiem, że ta odpowiedź jest stara, ale IMO to niezwykle przydatna funkcja, np .: docs.mongodb.com/manual/core/index-ttl
Madbreaks
dodanie tej funkcji do postgresql wymagałoby dużo pracy, np. tworzenie klucza obcego wymagałoby innych reguł ...
Jasen