Apakah ada cara untuk mengatur waktu "kedaluwarsa", setelah entri data secara otomatis dihapus di PostgreSQL?

107

Apakah ada cara untuk mengatur waktu "kedaluwarsa" pada entri data di PostgreSQL ? Saya sedang memikirkan sesuatu yang setara dengan EXPIREdi Redis .

Saya tidak ingin menyimpan stempel waktu dan kemudian secara manual membuat kode tugas cron untuk memeriksa entri apa yang telah kedaluwarsa.

Saya mencoba mencari tahu apakah ada fitur asli di PostgreSQL yang akan menyediakan fungsionalitas semacam ini, atau apakah masuk akal untuk meminta fitur semacam itu untuk rilis mendatang.

Pensierinmusica
sumber
1
Ada diskusi di milis postgresql postgresql.org/message-id/…
vonPetrushev

Jawaban:

105

Tidak ada fitur kedaluwarsa bawaan tetapi jika tujuan Anda adalah secara otomatis kedaluwarsa bidang dan memiliki logika yang terkandung dalam database Anda (dan dengan demikian tidak ada ketergantungan luar seperti pekerjaan cron) maka Anda selalu dapat menulis pemicu. Di bawah ini adalah contoh pemicu yang menghapus baris dari tabel yang memiliki stempel waktu lebih dari 1 menit. Ini dijalankan setiap kali baris baru dimasukkan ke dalam tabel yang sama. Anda jelas dapat mengatur pemicu untuk dieksekusi pada kondisi lain dan untuk berbagai tanggal kedaluwarsa sesuai kebutuhan. Saya menggunakan situs web berikut sebagai dasar untuk ini: 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
sumber
1
@caeus mungkin bergantung pada cache dan pengindeksan
Nimrod
39
-1. Imho, pemicu bukanlah cara Anda harus menangani fitur database yang hilang, karena pemicu sulit untuk diuji, sulit dipelihara, dan hanya menyebalkan. Jujurlah dan terapkan dalam aplikasi Anda. :)
Bastian Voigt
2
Setuju, saya pikir memeriksa catatan lama dan menghapusnya di setiap sisipan adalah solusi yang sangat buruk dalam hal kinerja. Tidak sulit untuk mengatur bahkan sesuatu seperti skrip pekerjaan CRON yang mengeksekusi membutuhkan SQL, misalnya.
zarkone
kinerja harus cukup baik jika ada indeks pada waktu kadaluwarsa.
Jasen
2
1 untuk solusi Brett. Untuk sesuatu seperti tabel sesi di mana Anda hanya ingin pengguna memiliki satu sesi, menurut saya pemicu pada INSERT apa pun ke tabel sesi, untuk memastikan bahwa setiap pengguna hanya memiliki satu sesi, adalah kasus penggunaan yang sangat valid . Orang-orang terobsesi jika ada sesuatu yang "dapat diuji" sehingga mereka menulis solusi yang lebih kompleks (yang kemudian membutuhkan pengujian berat) daripada beberapa fungsi sederhana yang mereka yakini tidak akan rusak.
corysimmons
8

Tidak. Tidak ada fitur seperti itu.

Saya tidak dapat melihat apa yang dilakukannya lebih dari (1) hanya stempel waktu "kedaluwarsa" atau (2) stempel waktu + cron-job / pgAgent.

Ini tidak terdengar seperti fitur umum yang akan ditambahkan ke inti. Anda cukup membuat kode ekstensi untuk menangani hal semacam ini, baik dengan tanda centang yang dipanggil dari cron-job atau mungkin proses background-worker .

Saya tidak melihat apa-apa di pgxn , jadi sepertinya belum banyak permintaan untuk itu.

Richard Huxton
sumber
3
Saya tahu jawaban ini sudah lama tetapi IMO ini adalah fitur yang sangat berguna, misalnya: docs.mongodb.com/manual/core/index-ttl
Madbreaks
itu akan membutuhkan banyak pekerjaan untuk menambahkan fitur ini ke postgresql, misalnya, pembuatan kunci asing akan membutuhkan aturan yang berbeda ...
Jasen