PostGIS教程学习二十二:使用触发器追踪历史编辑操作

PostGIS教程学习二十二:使用触发器追踪历史编辑操作

生产环境下数据库的一个常见要求是能够跟踪用户编辑数据的历史:数据在两个日期之间是如何变化的,是谁操作的,以及它们哪些内容变化了?一些GIS系统通过在客户端接口中包含更改管理功能来跟踪用户的编辑数据操作,但这增加了客户端编辑工具的复杂性。

使用数据库和数据库的触发器机制,可以对任何表进行编辑历史跟踪,从而让客户端保持对编辑表的简单“直接编辑”(客户端不用负责追踪编辑历史的功能,只负责CRUD)。

历史跟踪的工作方式是增加一个记录编辑历史的历史表,为每个编辑操作保留历史记录。历史表包含如下信息:

如果编辑表中创建了一条新记录,则保留新记录添加的时间、操作的用户。
如果编辑表中的一条记录被删除,保留记录被删除的时间、操作的用户。
如果编辑表中的一条记录被更新,则添加删除信息(针对旧状态)和创建信息(针对新状态)。

文章目录

  • PostGIS教程学习二十二:使用触发器追踪历史编辑操作
  • 一、创建历史表
  • 二、操作编辑表
    • 2.1、SQL编辑
  • 三、查找历史表
  • 四、参考资料


一、创建历史表

使用历史表的信息,可以恢复任何时间点编辑表的状态。在本例中,我们将针对nyc_streets表创建历史表,从而追踪nyc_streets表的编辑历史。

1)首先,添加一个新的nyc_streets_history表。这是我们将用来存储所有编辑历史信息的历史表。除了包含nyc_streets表的所有字段外,我们还为历史表增加了五个字段:

hid —— 历史表的主码
created —— 编辑表中对应记录被创建的时间
created_by ——编辑表中对应记录被创建的操作用户
deleted —— 编辑表中对应记录被删除的时间
deleted_by —— 编辑表中对应记录被删除的操作用户

CREATE TABLE nyc_streets_history (
  hid SERIAL PRIMARY KEY,
  gid INTEGER,
  id FLOAT8,
  name VARCHAR(200),
  oneway VARCHAR(10),
  type VARCHAR(50),
  geom GEOMETRY(MultiLinestring,26918),
  created TIMESTAMP,		-- 时间戳(无时区)
  created_by VARCHAR(32),
  deleted TIMESTAMP,
  deleted_by VARCHAR(32)
);

2)接下来,我们将编辑表nyc_streets的当前状态导入到历史表中,这样我们就有一个可以追踪历史编辑的起点。注意,我们插入了创建时间(created)和创建用户(created_by),但删除相关信息为空。

INSERT INTO nyc_streets_history
  (gid, id, name, oneway, type, geom, created, created_by)
   SELECT gid, id, name, oneway, type, geom, now(), current_user
   FROM nyc_streets;

3)现在,我们需要为编辑表创建三个触发器,用于插入、删除和更新操作。首先我们创建触发器函数(PostgreSQL的触发器动作体只能是函数),然后将它们作为触发器动作体绑定到表中。

对于INSERT操作,我们只需记录创建时间(created)和创建用户(created_by)信息并将该新记录添加到历史表中。

CREATE OR REPLACE FUNCTION nyc_streets_insert() RETURNS trigger AS
$$
  BEGIN
    INSERT INTO nyc_streets_history
      (gid, id, name, oneway, type, geom, created, created_by)
    VALUES
      (NEW.gid, NEW.id, NEW.name, NEW.oneway, NEW.type, NEW.geom,
       current_timestamp, current_user);
    RETURN NEW;
  END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER nyc_streets_insert_trigger
AFTER INSERT ON nyc_streets
FOR EACH ROW 
EXECUTE PROCEDURE nyc_streets_insert();

对于DELETE操作,我们只要将对应的历史记录(且deleted字段是NULL)标记为已删除。

CREATE OR REPLACE FUNCTION nyc_streets_delete() RETURNS trigger AS
$$
  BEGIN
    UPDATE nyc_streets_history
      SET deleted = current_timestamp, deleted_by = current_user
      WHERE deleted IS NULL and gid = OLD.gid;
    RETURN NULL;
  END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER nyc_streets_delete_trigger
AFTER DELETE ON nyc_streets
FOR EACH ROW 
EXECUTE PROCEDURE nyc_streets_delete();

对于UPDATE操作,我们首先将对应的历史记录标记为已删除,然后插入更新状态的新记录。

CREATE OR REPLACE FUNCTION nyc_streets_update() RETURNS trigger AS
$$
  BEGIN

    UPDATE nyc_streets_history
      SET deleted = current_timestamp, deleted_by = current_user
      WHERE deleted IS NULL and gid = OLD.gid;

    INSERT INTO nyc_streets_history
      (gid, id, name, oneway, type, geom, created, created_by)
    VALUES
      (NEW.gid, NEW.id, NEW.name, NEW.oneway, NEW.type, NEW.geom,
       current_timestamp, current_user);

    RETURN NEW;

  END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER nyc_streets_update_trigger
AFTER UPDATE ON nyc_streets
FOR EACH ROW 
EXECUTE PROCEDURE nyc_streets_update();

二、操作编辑表

现在启用了历史表,我们可以对编辑表进行编辑,并在历史表中看到日志条目。

请注意这种数据库支持的追踪编辑历史的强大功能:无论使用什么工具进行编辑,比如SQL命令行、基于Web的JDBC工具,还是像QGIS这样的桌面工具,编辑历史都会被持续追踪。

2.1、SQL编辑

让我们把这两条名字叫做“Cumberland Walk”的街道改成更时髦的“Cumberland Wynde”:

UPDATE nyc_streets SET name = 'Cumberland Wynde'
WHERE name = 'Cumberland Walk'; 

更新这两条街道将会把历史表中原来的街道标记为已删除,删除时间为现在,以及再添加具有新名称的两条新街道。

SELECT hid, gid, name, created, created_by, deleted, deleted_by
FROM nyc_streets_history 
WHERE name = 'Cumberland Walk' OR name = 'Cumberland Wynde'
ORDER BY hid;

在这里插入图片描述

三、查找历史表

既然我们有了历史表,那还有什么用处呢?它对"时间旅行"很有用!要旅行到特定的时刻T(即查看T时刻历史表的状态),我们需要构造一个查询,查询出符合如下规则的记录:

所有在时刻T之前创建且目前尚未删除的记录。
所有在时刻T之前创建,但在T之后删除的记录。
我们可以使用这个逻辑来创建过去某个时刻T对应的数据状态的视图。假设我们的所有测试编辑都发生在过去30分钟内,那我们可以创建一个30分钟前历史表数据状态的视图:

– 30分钟前的历史表的数据状态
– 记录必须在30分钟前创建,并且现在没被删除(DELETED为NULL)
– 或在过去30分钟内已删除的

CREATE OR REPLACE VIEW nyc_streets_thirty_min_ago AS
  SELECT * FROM nyc_streets_history
  WHERE created < (now() - '30min'::interval)
      AND ( deleted IS NULL OR deleted > (now() - '30min'::interval) );

我们还可以创建视图来显示被特定用户(比如用户postgres)编辑的记录:

CREATE OR REPLACE VIEW nyc_streets_postgres AS
  SELECT * FROM nyc_streets_history
  WHERE created_by = 'postgres' OR deleted_by = 'postgres';

四、参考资料

PostgreSQL触发器官方文档
PostgreSQL过程化语言(PL/pgSQL)官方文档

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

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

相关文章

代码随想录算法训练营第38天(动态规划01 ● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

动态规划part01 理论基础509. 斐波那契数70. 爬楼梯解题思路 746. 使用最小花费爬楼梯解题思路 今天正式开始动态规划&#xff01; 理论基础 理论基础讲解 视频讲解 动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区分于贪心&#xff0c;贪心没有状态…

1451A/D/F捷变信号发生器

01 1451A/D/F捷变信号发生器 产品综述&#xff1a; 1451系列捷变信号发生器采用直接数字合成&#xff08;DDS&#xff09;技术和直接模拟合成技术&#xff08;ADS&#xff09;相结合的设计方案&#xff0c;实现覆盖10MHz~3/20/40GHz全频段的频率捷变&#xff0c;捷变时间小于…

02链表:19、删除链表的倒数第N个节点

19、删除链表的倒数第N个节点 文章目录 19、删除链表的倒数第N个节点方法一&#xff1a;快慢指针 思路&#xff1a;使用虚拟头节点快慢指针&#xff0c;fast指针先走n1&#xff0c;直到为null&#xff0c;slow节点刚好在删除元素前一个位置&#xff0c;方便操作 重点&#xff1…

代码随想录算法训练营29期|day38 任务以及具体安排

第九章 动态规划part01 509. 斐波那契数 //非压缩状态的版本 class Solution {public int fib(int n) {if (n < 1) return n; int[] dp new int[n 1];dp[0] 0;dp[1] 1;for (int index 2; index < n; index){dp[index] dp[index - 1] dp[index - 2];}r…

《金融时报》:直面“雪球”风波 究竟影响几何?

“他们给我推荐的时候说是只要市场不大跌&#xff0c;我就能按照年化20%获得收益&#xff0c;当时我看大盘走势&#xff0c;也认为跌那么多的概率不大。”李先生告诉《金融时报》记者&#xff0c;他当初被银行客户经理推荐“雪球”产品并头脑一热买了的时候&#xff0c;以为按照…

leetcode刷题(剑指offer) 103.二叉树的锯齿形层序遍历

103.二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输入&#xff1a…

幻兽帕鲁能在Mac上运行吗?幻兽帕鲁Palworld新手攻略

幻兽帕鲁能在Mac上运行吗&#xff1f; 《幻兽帕鲁》目前还未正式登陆Mac平台&#xff0c;不过通过一些方法是可以让游戏在该平台运行的。 虽然游戏不能在最高配置下运行&#xff0c;但如果你安装了CrossOver这个软件&#xff0c;就可以玩了。这是为Mac、Linux和ChromeOS等设计…

前端JavaScript篇之对对象与数组的解构的理解、如何提取高度嵌套的对象里的指定属性?

目录 对对象与数组的解构的理解如何提取高度嵌套的对象里的指定属性&#xff1f; 对对象与数组的解构的理解 对象与数组的解构是一种通过模式匹配的方式&#xff0c;从对象或数组中提取值&#xff0c;并将其赋给变量的过程。它可以让我们以一种简洁的方式访问和使用对象或数组…

爬虫笔记(三):实战qq登录

咳咳&#xff0c;再这样下去会进橘子叭hhhhhh 以及&#xff0c;这个我觉得大概率是成功的&#xff0c;因为测试了太多次&#xff0c;登录并且验证之后&#xff0c;qq提醒我要我修改密码才可以登录捏QAQ 1. selenium 有关selenium具体是啥&#xff0c;这里就不再赘述了&#x…

ZKFair Pass (FEB) NFT 上线 10 分钟售罄,市场反响激烈

据 ZKFair 推特显示&#xff0c;1 月 31 日晚间&#xff0c;ZKFair 与 Element 联合发布的 2 万张限量 ZKFair Pass&#xff08;FEB&#xff09;于 10 分钟内售罄。ZKFair Pass (FEB) 是 ZKFair 和 Element 联合推出的限时权益卡&#xff0c;总量 2 万张&#xff0c;持卡人将获…

基于junit4搭建自定义的接口自动化测试框架

随着业务的逐步稳定&#xff0c;对于接口的改动也会逐渐变少。更多的是对业务逻辑的优化&#xff0c;功能实现的完善。对于测试来说&#xff0c;重复繁琐的功能测试不仅效率低下&#xff0c;而且耗费一定的人力资源。笔者支持的信息流业务下的一个图文管理平台就是一个功能较为…

机器学习入门-----sklearn

机器学习基础了解 概念 机器学习是人工智能的一个实现途径 深度学习是机器学习的一个方法发展而来 定义:从数据中自动分析获得模型,并利用模型对特征数据【数据集:特征值+目标值构成】进行预测 算法 数据集的目标值是类别的话叫做分类问题;目标值是连续的数值的话叫做回…

【开源】SpringBoot框架开发无代码动态表单系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 动态类型模块2.2 动态文件模块2.3 动态字段模块2.4 动态值模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 动态类型表3.2.2 动态文件表3.2.3 动态字段表3.2.4 动态值表 四、系统展示五、核心代码5.1 查询档案类型5.…

智慧文旅:驱动文化与旅游融合发展的新动力

随着科技的快速发展和人们生活水平的提高&#xff0c;文化和旅游的融合成为了时代发展的必然趋势。智慧文旅作为这一趋势的引领者&#xff0c;通过先进的信息技术手段&#xff0c;推动文化与旅游的深度融合&#xff0c;为产业的发展注入新的活力。本文将深入探讨智慧文旅如何成…

数据库运维工作量直接减少 50%,基于大模型构建智能问答系统的技术分享

本文源自百度智能云数据库运维团队的实践&#xff0c;深入探讨了基于大模型构建「知识库智能问答系统」的设计过程和应用。 全文包括了总体的技术方案选型、各个模块的设计实现、重点难点问题的突破、以及目前的落地场景应用等。 该系统自从内部上线以来&#xff0c;整体的回…

大语言模型之LlaMA系列-LlaMA 2及LlaMA_chat(下)

多转一致性的系统消息 - System Message for Multi-Turn Consistency 在对话设置中&#xff0c;某些指示应适用于所有对话轮次。 例如&#xff0c;简洁地响应&#xff0c;或"充当"某个公众人物。当我们向Llama 2-Chat提供此类指示时&#xff0c;后续应响应始终遵守约…

十、Qt三维图表

一、Data Visualization模块概述 Data Visualization的三维显示功能主要有三种三维图形来实现&#xff0c;三各类的父类都是QAbstract3DGraph&#xff0c;从QWindow继承而来。这三类分别是&#xff1a;三维柱状图Q3DBar三维空间散点Q3DScatter三维曲面Q3DSurface 1、相关类的…

混乱字母排序——欧拉路数论

题目描述 小明接到一个神秘的任务&#xff1a;对于给定的 n 个没有顺序的字母对&#xff08;无序代表这两个字母可以前后顺序颠倒&#xff0c;区分大小写&#xff09;。请构造一个有 (n1) 个字母的混乱字符串使得每个字母对都在这个字符串中出现。 输入输出格式 输入格式 第…

蓝桥杯备战——10.超声波模块

1.分析原理图 蓝桥杯单片机板子的原理图做的简直是依托答辩&#xff0c;乱糟糟的不说还弄成黑白的&#xff0c;明明很简单的东西&#xff0c;弄成一大堆。 可以看到&#xff0c;J2跳线帽如果P10接N_A1,P11接N_B1就是用作超声波功能。N_A1用作发生超声波功能&#xff0c;而N_B1…

【blender插件】(1)快速开始

特性 blender的python API有如下特性: 编辑用户界面可以编辑的任意数据(场景,网格,粒子等)。修改用户首选项、键映射和主题。运行自己的配置运行工具。创建用户界面元素,如菜单、标题和面板。创建新的工具。场景交互式工具。创建与Blender集成的新渲染引擎。修改模型的数据…