Có cách nào để đặt thời gian “hết hạn”, sau đó mục nhập dữ liệu sẽ tự động bị xóa trong PostgreSQL không?


107

Có cách nào để đặt một số loại thời gian "hết hạn" trên các mục dữ liệu trong PostgreSQL không? Tôi đang nghĩ về điều gì đó tương đương với EXPIRERedis .

Tôi không tìm cách lưu trữ dấu thời gian và sau đó viết mã thủ công một số loại công việc cron để kiểm tra những mục nhập nào đã hết hạn.

Tôi đang cố gắng tìm hiểu xem có bất kỳ tính năng gốc nào trong PostgreSQL sẽ cung cấp loại chức năng này hay không hoặc liệu có hợp lý khi yêu cầu tính năng như vậy cho các bản phát hành trong tương lai hay không.


1
Đã có cuộc thảo luận trên danh sách gửi thư postgresql postgresql.org/message-id/…
vonPetrushev

Câu trả lời:


105

Không có tính năng hết hạn được tích hợp sẵn nhưng nếu mục tiêu của bạn là tự động hết hạn các trường và có logic chứa trong cơ sở dữ liệu của bạn (và do đó không phụ thuộc bên ngoài như cron job) thì bạn luôn có thể viết trình kích hoạt. Dưới đây là ví dụ về trình kích hoạt xóa các hàng khỏi bảng có dấu thời gian cũ hơn 1 phút. Nó được thực thi bất cứ khi nào một hàng mới được chèn vào cùng một bảng đó. Bạn rõ ràng có thể đặt trình kích hoạt để thực thi trên các điều kiện khác và cho các ngày hết hạn khác nhau nếu cần. Tôi đã sử dụng trang web sau làm cơ sở cho việc này: 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 có lẽ phụ thuộc vào bộ nhớ đệm và lập chỉ mục
Nimrod

39
-1. Imho, trình kích hoạt không phải là cách bạn nên đối phó với các tính năng cơ sở dữ liệu bị thiếu, bởi vì trình kích hoạt khó kiểm tra, khó bảo trì và chỉ là một nỗi đau. Hãy trung thực và thực hiện nó trong ứng dụng của bạn. :)
Bastian Voigt

2
Đồng ý, tôi nghĩ rằng kiểm tra các bản ghi cũ và xóa nó trên mỗi lần chèn là giải pháp thực sự khủng khiếp về mặt hiệu suất. Không quá khó để thiết lập một thứ gì đó như tập lệnh công việc CRON, chẳng hạn như thực thi yêu cầu SQL.
zarkone

perfprmance phải khá tốt nếu có chỉ số về thời gian hết hạn.
Jasen

2
+1 cho giải pháp của Brett. Đối với một cái gì đó giống như bảng phiên mà bạn chỉ muốn người dùng có một phiên duy nhất, tôi nghĩ rằng một kích hoạt trên bất kỳ CHÈN vào bảng phiên, để đảm bảo rằng mỗi người dùng chỉ có một phiên, là trường hợp sử dụng hoàn toàn hợp lệ . Mọi người ám ảnh về việc nếu một cái gì đó "có thể kiểm tra được", vì vậy họ viết các giải pháp phức tạp hơn (sau đó cần thử nghiệm nặng) thay vì một số chức năng đơn giản mà họ có thể tự tin sẽ không phá vỡ.
corysimmons

8

Không. Không có tính năng này.

Tôi không thể thấy nó làm được gì ngoài (1) chỉ là dấu thời gian "hết hạn" hoặc (2) dấu thời gian + cron-job / pgAgent.

Nó không giống như một tính năng chung sẽ được thêm vào cốt lõi. Bạn hoàn toàn có thể viết mã một tiện ích mở rộng để xử lý loại việc này, với một dấu kiểm được gọi từ cron-job hoặc có thể là một quy trình background-worker .

Tôi không thấy bất cứ điều gì trên pgxn , vì vậy có lẽ là chưa có nhiều nhu cầu về nó.


3
Tôi biết câu trả lời này đã cũ nhưng IMO đó là một tính năng cực kỳ hữu ích, ví dụ: docs.mongodb.com/manual/core/index-ttl
Madbreaks

nó sẽ yêu cầu rất nhiều công việc để thêm tính năng này vào postgresql, ví dụ: tạo khóa ngoại sẽ cần các quy tắc khác nhau ...
Jasen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.