在 PostgreSQL 里如何实现数据的自动清理和过期处理?

文章目录

  • 一、使用 `TIMESTAMP` 列和定期任务
  • 二、使用事件触发器(Event Triggers)
  • 三、使用分区表(Partitioned Tables)
  • 四、结合存储过程和定时任务
    • 示例场景
    • 实现步骤
    • 测试与验证

美丽的分割线

PostgreSQL


在 PostgreSQL 中,可以通过多种方式实现数据的自动清理和过期处理,以确保数据库不会因为存储过多过时或不再需要的数据而导致性能下降和存储空间浪费。以下是一些常见的方法及详细示例:

美丽的分割线

一、使用 TIMESTAMP 列和定期任务

  1. 创建表时添加 TIMESTAMP 列用于记录数据的创建时间或最后更新时间

假设我们有一个名为 orders 的表,用于存储订单信息,其中包含一个 created_at 列来记录订单创建的时间:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_amount DECIMAL(10, 2),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 创建定期任务(例如使用 cron 或操作系统的定时任务)来执行删除过期数据的 SQL 语句

假设我们希望删除创建时间超过 30 天的订单数据,可以编写如下的 SQL 语句:

DELETE FROM orders WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '30 days';

然后,可以使用操作系统的定时任务工具(如 cron 在 Linux 系统中)来定期执行上述 SQL 语句。假设每天凌晨 2 点执行清理任务,cron 表达式可能如下:

0 2 * * * psql -U your_username -d your_database -c "DELETE FROM orders WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '30 days';"

上述方法的优点是简单直接,易于理解和实现。缺点是需要依赖操作系统的定时任务机制,并且可能存在一定的时间延迟,即在到达指定的清理时间点和实际执行清理操作之间可能存在时间差。

美丽的分割线

二、使用事件触发器(Event Triggers)

PostgreSQL 提供了事件触发器的功能,可以在特定的数据库事件(如 INSERTUPDATEDELETE 等)发生时执行自定义的函数。

  1. 首先,创建一个函数来处理数据的过期清理逻辑
CREATE OR REPLACE FUNCTION expire_orders() RETURNS TRIGGER AS
$$
BEGIN
    DELETE FROM orders WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '30 days';
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;
  1. 然后,创建事件触发器
CREATE TRIGGER trigger_expire_orders
AFTER INSERT OR UPDATE ON orders
EXECUTE FUNCTION expire_orders();

这样,每当对 orders 表进行插入或更新操作时,都会触发 expire_orders 函数进行过期数据的清理。

这种方法的优点是实时性较好,数据过期处理能够在相关操作发生时立即进行。缺点是可能会对正常的插入或更新操作带来一定的性能开销,尤其是在数据量较大的情况下。

美丽的分割线

三、使用分区表(Partitioned Tables)

分区表是将一个大表按照某种规则分成多个较小的子表,从而可以更有效地管理和操作数据。

  1. 创建分区表

假设按照月份对订单表进行分区:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_amount DECIMAL(10, 2),
    created_at TIMESTAMP
) PARTITION BY RANGE (created_at);

CREATE TABLE orders_2023_01 PARTITION OF orders
    FOR VALUES FROM ('2023-01-01 00:00:00') TO ('2023-01-31 23:59:59');

CREATE TABLE orders_2023_02 PARTITION OF orders
    FOR VALUES FROM ('2023-02-01 00:00:00') TO ('2023-02-28 23:59:59');

-- 以此类推创建其他月份的分区表
  1. 定期删除过期的分区

可以通过 DROP TABLE 语句来删除过期的分区,例如每月月初删除上个月的分区:

DROP TABLE orders_2023_01;

分区表的优点是在处理大量数据时性能较好,并且删除过期分区的操作相对简单高效。缺点是创建和管理分区表的过程相对复杂,需要提前规划好分区策略。

美丽的分割线

四、结合存储过程和定时任务

  1. 创建存储过程
CREATE OR REPLACE PROCEDURE clean_expired_data()
LANGUAGE plpgsql
AS $$
BEGIN
    DELETE FROM orders WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '30 days';
END;
$$;
  1. 使用定时任务调用存储过程

与前面提到的使用定时任务执行 SQL 语句类似,只是这里改为调用存储过程:

0 2 * * * psql -U your_username -d your_database -c "CALL clean_expired_data();"

这种方法结合了存储过程的封装性和定时任务的灵活性,便于维护和管理复杂的清理逻辑。

下面通过一个综合示例来展示如何在实际应用中使用以上方法的组合:

示例场景

假设我们有一个用户活动日志表 user_activity_log,用于记录用户在系统中的各种操作,包括操作时间 activity_time 和操作详情 activity_details。我们希望定期清理超过 90 天的活动日志。

实现步骤

  1. 创建表
CREATE TABLE user_activity_log (
    log_id SERIAL PRIMARY KEY,
    user_id INT,
    activity_details TEXT,
    activity_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  1. 创建清理数据的存储过程
CREATE OR REPLACE PROCEDURE clean_expired_activity_logs()
LANGUAGE plpgsql
AS $$
BEGIN
    DELETE FROM user_activity_log WHERE activity_time < CURRENT_TIMESTAMP - INTERVAL '90 days';
END;
$$;
  1. 设置操作系统定时任务
    假设使用 Linux 的 cron 服务,每天凌晨 1 点执行清理任务:
0 1 * * * psql -U your_username -d your_database -c "CALL clean_expired_activity_logs();"

测试与验证

在实际运行一段时间后,可以通过查询表中的数据来验证清理操作是否按照预期进行:

SELECT * FROM user_activity_log;

检查是否只有最近 90 天内的活动日志存在。


美丽的分割线

🎉相关推荐

  • 🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!
  • 📚领书:PostgreSQL 入门到精通.pdf
  • 📙PostgreSQL 中文手册
  • 📘PostgreSQL 技术专栏

PostgreSQL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/788035.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring系统学习 - AOP之基于注解的AOP和XML的AOP

上一篇我们围绕了AOP中代理模式的使用&#xff0c;这篇我们将主要围绕AOP的相关术语介绍&#xff0c;以及重点围绕基于注解的AOP进行相关知识的概述和使用说明。 AOP的相关术语 切面&#xff08;Aspect&#xff09;&#xff1a;切面是一个模块化的横切关注点&#xff0c;它包含…

mybatis-plus参数绑定异常

前言 最近要搞个发票保存的需求&#xff0c;当发票数据有id时说明是发票已经保存只需更新发票数据即可&#xff0c;没有id时说明没有发票数据需要新增发票&#xff1b;于是将原有的发票提交接口改造了下&#xff0c;将调用mybatis-plus的save方法改为saveOrUpdate方法&#xff…

C++:多态(继承)

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;多态》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 :maple_leaf:多态的概念:maple_leaf:继承中的多态1.:leaves:虚函数表 :…

更亮更好听的户外耳机,下班之后畅快运动,哈氪聆光体验

在当今市场上&#xff0c;蓝牙耳机种类繁多&#xff0c;现在正值酷热的夏季&#xff0c;有必要准备一副适合户外活动的蓝牙耳机&#xff0c;对此&#xff0c;我觉得气传导耳机更适合在户外锻炼或散步时使用。这种耳机设计通常为后挂式&#xff0c;不仅佩戴舒适&#xff0c;而且…

宝塔面板运行Admin.net框架

准备 宝塔安装 .netcore安装 Admin.net框架发布 宝塔面板设置 完结撒花 1.准备 服务器/虚拟机一台 系统Windows server / Ubuntu20.04&#xff08;本贴使用的是Ubuntu20.04版本系统&#xff09; Admin.net开发框架 先安装好服务器系统&#xff0c;这里就不做安装过程描述了&…

安装nodejs | npm报错

nodejs安装步骤: 官网&#xff1a;https://nodejs.org/en/ 在官网下载nodejs: 双击下载下来的msi安装包&#xff0c;一直点next&#xff0c;我选的安装目录是默认的: 测试是否安装成功&#xff1a; 输入cmd打开命令提示符&#xff0c;输入node -v可以看到版本&#xff0c;说…

“郑商企航”暑期社会实践赴美丽美艳直播基地开展调研

马常旭文化传媒网讯&#xff08;记者张明辉报道&#xff09;导读&#xff1a;2024 年 7 月 3 日&#xff0c;商学院暑期社会实践团“郑商企航”在河南省郑州市新密市岳村镇美丽美艳直播基地&#xff0c;展开了一场意义非凡的考察活动&#xff0c;团队成员深度调研了直播基地的产…

DMA方式的知识点笔记

苏泽 “弃工从研”的路上很孤独&#xff0c;于是我记下了些许笔记相伴&#xff0c;希望能够帮助到大家 目录 1. DMA基本概念 2. DMA传送过程 易错点 DMA控制器操作流程 3. DMA传送方式 这是单总线的结果 &#xff08;CPU说了算 所以不会产生于CPU的冲突&#xff09; 这…

idea创建dynamic web project

由于网课老师用的是eclipse,所以又得自己找教程了…… 解决方案&#xff1a; https://blog.csdn.net/Awt_FuDongLai/article/details/115523552

仕考网:公务员体检对视力有要求吗?

公务员招聘过程中的体检标准对视力有具体要求&#xff0c;根据不同的岗位职责有所差异。通常情况下&#xff0c;如果申请者双眼经过矫正后视力均低于4.8(小数视力0.6)&#xff0c;则会被视为不合格。 对于某些特殊岗位&#xff0c;如J察等&#xff0c;单侧裸眼视力若低于4.8也…

【教程】Github Page 添加自定义域名

目录 前言购买域名验证自定义域名映射自定义域名记录类型注意点参考 前言 Github Page 是 Github 提供的一个可以从 Github 仓库上托管静态网站的功能服务。默认当你建立起一个仓库后&#xff0c;在对应会有一个可供浏览的静态网站&#xff0c;例如 https://eternaldeath.gith…

【动态规划Ⅵ】背包问题 /// 组合问题

背包问题 什么是背包问题0-1背包问题分数背包完全背包问题重复背包问题 背包问题例题416. 分割等和子集474. 一和零 完全平方数279. 完全平方数322. 零钱兑换 排列与组合组合&#xff0c;无重复&#xff1a;518. 零钱兑换 II排列&#xff0c;可重复&#xff1a;377. 组合总和 Ⅳ…

MySQL架构优化及SQL优化

变更项目的整体架构是性能收益最大的方式。主要涉及两方面&#xff0c;一方面是从整个项目角度&#xff0c;引入一些中间件优化整体性能&#xff0c;另一方面是调整MySQL的部署架构&#xff0c;确保能承载更大的流量访问&#xff0c;提高数据层的整体吞吐。 1. 引入缓存中间件…

语义分割和实例分割区别?

语义分割&#xff1a;将图像中的每个像素分配给其对应的语义类别&#xff0c;其主要针对于像素&#xff0c;或者说它是像素级别的图像分割方法。&#xff1a;语义分割的目的是为了从像素级别理解图像的内容&#xff0c;并为图像中的每个像素分配一个对象类。 实例分割&#xf…

泛微E9开发 控制Radio框字段打印是否仅显示选中项文字

控制Radio框字段打印是否仅显示选中项文字 1、需求说明2、实现方法3、扩展知识点控制Radio框字段打印是否仅显示选中项文字格式参数说明样例 1、需求说明 当我们对单选框进行打印时&#xff0c;往往会把所有的选项一起打印出来&#xff08;如下图所示&#xff09;&#xff0c;现…

【1】A-Frame整体介绍

1.A-Frame是什么&#xff1f; A-Frame 是一个用于构建虚拟现实 (VR) 体验的 Web 框架。 A-Frame 基于 HTML 之上&#xff0c;因此上手简单。但 A-Frame 不仅仅是 3D 场景图或标记语言&#xff1b;它还是一种标记语言。其核心是一个强大的实体组件框架&#xff0c;为 Three.js …

昇思MindSpore学习入门-模型模块自定义

基础用法示例 神经网络模型由各种层(Layer)构成&#xff0c;MindSpore提供构造神经网络层的基础单元Cell&#xff0c;基于Cell进行神经网络封装。下面使用Cell构造经典模型AlexNet。 如图所示&#xff0c;AlexNet由5个卷积层与3个全连接层串联构成&#xff0c;我们使用mindspo…

秋招Java后端开发冲刺——并发篇2(ThreadLocal、Future接口)

本文对ThreadLocal类和Future接口进行了总结概括&#xff0c;包括ThreadLocal类的原理、内存泄露等问题&#xff0c;和Future接口的使用等问题。 一、ThreadLocal 1. 介绍 ThreadLocal&#xff08;线程局部变量&#xff09;是Java中的一个类&#xff0c;线程通过维护一个本地…

探索安卓四大组件:活动、服务、广播接收器和内容提供者

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Android ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1. Activity&#xff08;活动&#xff09; 概述&#xff1a; 生命周期&#xff1a; 使用方法&#xff1a; 2. Service&…