มีวิธีตั้งเวลา“ หมดอายุ” หลังจากนั้นรายการข้อมูลจะถูกลบโดยอัตโนมัติใน PostgreSQL หรือไม่?


115

มีวิธีใดที่จะตั้งเรียงลำดับของ "หมดอายุ" เวลาในรายการข้อมูลในบางPostgreSQL ? ฉันคิดเกี่ยวกับสิ่งที่เทียบเท่ากับEXPIREใน Redis

ฉันไม่ต้องการจัดเก็บการประทับเวลาจากนั้นกำหนดรหัสงานcronบางประเภทด้วยตนเองเพื่อตรวจสอบว่ารายการใดหมดอายุแล้ว

ฉันกำลังพยายามค้นหาว่ามีคุณสมบัติดั้งเดิมใน PostgreSQL ที่จะให้ฟังก์ชันประเภทนี้หรือไม่หรือหากจะขอคุณสมบัติดังกล่าวเพื่อเผยแพร่ในอนาคต


1
มีการพูดคุยกันในรายชื่ออีเมล postgresql postgresql.org/message-id/…
vonPetrushev

คำตอบ:


110

ไม่มีคุณลักษณะการหมดอายุในตัว แต่ถ้าเป้าหมายของคุณคือการหมดอายุฟิลด์โดยอัตโนมัติและมีตรรกะอยู่ในฐานข้อมูลของคุณ (และไม่มีการพึ่งพาภายนอกเช่นงาน cron) คุณสามารถเขียนทริกเกอร์ได้ตลอดเวลา ด้านล่างนี้คือตัวอย่างของทริกเกอร์ที่ลบแถวออกจากตารางที่มีการประทับเวลาเก่ากว่า 1 นาที จะดำเนินการทุกครั้งที่มีการแทรกแถวใหม่ลงในตารางเดียวกัน เห็นได้ชัดว่าคุณสามารถตั้งค่าทริกเกอร์เพื่อดำเนินการตามเงื่อนไขอื่น ๆ และวันหมดอายุต่างๆได้ตามต้องการ ฉันใช้เว็บไซต์ต่อไปนี้เป็นพื้นฐานสำหรับสิ่งนี้: 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 อาจขึ้นอยู่กับการแคชและการจัดทำดัชนี
Nimrod

49
-1. อิมโฮทริกเกอร์ไม่ใช่วิธีที่คุณควรจัดการกับคุณสมบัติฐานข้อมูลที่ขาดหายไปเพราะทริกเกอร์นั้นยากต่อการทดสอบดูแลรักษายากและมีเพียงความเจ็บปวดที่ตูด ซื่อสัตย์และนำไปใช้ในแอปพลิเคชันของคุณ :)
Bastian Voigt

2
เห็นด้วยฉันคิดว่าการตรวจสอบบันทึกเก่าและลบออกในการแทรกแต่ละครั้งเป็นวิธีแก้ปัญหาที่แย่มากในแง่ของประสิทธิภาพ ไม่ยากที่จะตั้งค่าแม้แต่บางอย่างเช่นสคริปต์งาน CRON ซึ่งดำเนินการต้องใช้ SQL เป็นต้น
zarkone

perfprmance ควรจะค่อนข้างดีหากมีดัชนีเกี่ยวกับเวลาหมดอายุ
Jasen

3
+1 ให้กับโซลูชันของ Brett สำหรับบางอย่างเช่นตารางเซสชันที่คุณต้องการให้ผู้ใช้มีเซสชันเดียวเท่านั้นฉันคิดว่าทริกเกอร์บน INSERT ใด ๆ ไปยังตารางเซสชันเพื่อให้แน่ใจว่าผู้ใช้แต่ละคนมีเพียงเซสชันเดียวเป็นกรณีการใช้งานที่ถูกต้องอย่างสมบูรณ์ . ผู้คนหมกมุ่นอยู่กับว่าบางสิ่งบางอย่าง "ทดสอบได้" ดังนั้นพวกเขาจึงเขียนวิธีแก้ปัญหาที่ซับซ้อนมากขึ้น (ซึ่งจำเป็นต้องมีการทดสอบอย่างหนัก) แทนที่จะเป็นฟังก์ชันง่ายๆที่พวกเขามั่นใจได้ว่าจะไม่พัง
corysimmons

7

ไม่ไม่มีคุณสมบัติดังกล่าว

ฉันไม่เห็นว่ามันทำอะไรได้มากกว่า (1) แค่การประทับเวลา "หมดอายุ" หรือ (2) timestamp + cron-job / pgAgent

ฟังดูไม่เหมือนคุณสมบัติทั่วไปที่จะถูกเพิ่มเข้าไปในแกนกลาง คุณสามารถเขียนรหัสไฟล์ส่วนขยายเพื่อจัดการกับสิ่งนี้ได้โดยใช้เห็บที่เรียกจาก cron-job หรืออาจเป็นกระบวนการทำงานเบื้องหลัง

ฉันไม่เห็นอะไรในpgxnดังนั้นน่าจะยังไม่มีความต้องการมากนัก


3
ฉันรู้ว่าคำตอบนี้เก่า แต่ IMO เป็นคุณสมบัติที่มีประโยชน์อย่างไม่น่าเชื่อเช่นdocs.mongodb.com/manual/core/index-ttl
Madbreaks

จะต้องใช้งานมากมายในการเพิ่มคุณสมบัตินี้ใน postgresql เช่นการสร้างคีย์ต่างประเทศจะต้องมีกฎที่แตกต่างกัน ...
Jasen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.