有没有办法设置“过期”时间,之后在 PostgreSQL 中自动删除数据条目?
Posted
技术标签:
【中文标题】有没有办法设置“过期”时间,之后在 PostgreSQL 中自动删除数据条目?【英文标题】:Is there a way to set an "expiry" time, after which a data entry is automatically deleted in PostgreSQL? 【发布时间】:2014-11-20 17:06:09 【问题描述】:有什么方法可以为PostgreSQL 中的数据条目设置某种“到期”时间吗?我正在考虑类似于EXPIRE
in Redis 的东西。
我不想存储时间戳,然后手动编写某种cron 作业来检查哪些条目已过期。
我正在尝试找出 PostgreSQL 中是否有任何可以提供此类功能的本机功能,或者为将来的版本请求此类功能是否有意义。
【问题讨论】:
postgresql 邮件列表中有讨论postgresql.org/message-id/… 我知道这不是一个真正的答案,所以我将它作为评论留下。 Postgres 不打算以这种方式用于临时数据。使用 Redis。当你需要的工具已经存在并且运行良好时,没有理由让 Postgres 成为你需要的工具。 【参考方案1】:没有内置的过期功能,但如果您的目标是自动过期字段并将逻辑包含在您的数据库中(因此没有像 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)
【讨论】:
@caeus 可能依赖于缓存和索引 -1。恕我直言,触发器不是您应该处理缺少的数据库功能的方式,因为触发器很难测试,难以维护,而且很麻烦。诚实并在您的应用程序中实现它。 :) 同意,我认为在每次插入时检查旧记录并删除它在性能方面真的很糟糕。例如,即使是执行需要 SQL 的 CRON 作业脚本之类的设置也不难。 如果有关于过期时间的索引,性能应该是相当不错的。 +1 到 Brett 的解决方案。对于像会话表这样的东西,您只希望用户拥有一个会话,我认为任何 INSERT 到会话表的触发器,以确保每个用户只有一个会话,是一个完全有效的用例.人们对某些东西是否“可测试”很着迷,因此他们编写了更复杂的解决方案(然后需要大量测试),而不是一些他们可以确信不会破坏的简单功能。【参考方案2】:没有。没有这样的功能。
我看不出它比 (1) 只是“过期”时间戳或 (2) 时间戳 + cron-job/pgAgent 所做的更多。
这听起来不像是要添加到核心的一般功能。你可以很简单地编写一个 extension 来处理这种事情,或者从 cron-job 调用一个滴答声,或者可能是一个 background-worker 进程。
我在pgxn 上没有看到任何东西,所以大概还没有太多需求。
【讨论】:
我知道这个答案很旧,但 IMO 这是一个非常有用的功能,例如:docs.mongodb.com/manual/core/index-ttl 将这个特性添加到postgresql需要大量的工作,例如,外键创建需要不同的规则......以上是关于有没有办法设置“过期”时间,之后在 PostgreSQL 中自动删除数据条目?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法为我在 ignitecache 中插入的不同元素设置不同的到期时间?