首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能为postgres构建一个撤销框架?

是否有可能为postgres构建一个撤销框架?
EN

Database Administration用户
提问于 2013-06-25 14:39:07
回答 2查看 3.2K关注 0票数 2

我正在考虑一个表,它将自动记录到其他表中的所有事务,并使用命令撤消这些修改。因此,每次发出UNDO()命令时,您都会从log表中读取语句并执行它。

示例:

你发布了一个

代码语言:javascript
复制
INSERT INTO sales (id, client_id, product, value) 
VALUES (4621, 231, 'Hamburguer', 500)

所以日志触发器可以

代码语言:javascript
复制
INSERT INTO log (undo) VALUES ('DELETE FROM sales WHERE id = 4621')

当您发出UNDO()时,该函数将发出类似于EVAL(SELECT undo FROM log ORDER BY id DESC LIMIT 1)的内容。

有经验的人,请告诉我这是否可能。

EN

回答 2

Database Administration用户

发布于 2013-06-26 00:20:24

理论上可以,但在实践中,您会发现取消单个更改是有点困难的,因为外键,等等。

考虑:

代码语言:javascript
复制
CREATE TABLE a (
    id integer primary key
);

CREATE TABLE b (
    id integer primary key, 
    a_id integer not null references a(id) on delete cascade
);

INSERT INTO a(id) VALUES (1),(2),(3);
INSERT INTO b(id, a_id) VALUES (10,1), (20,2), (30,3);

现在,说你做的是:

代码语言:javascript
复制
DELETE FROM a WHERE id = 2;

这将导致从(20,2)中自动删除b。当您想要撤消此更改时,您需要知道从a中删除也导致了b中的删除。

同样,说你:

代码语言:javascript
复制
DELETE FROM b WHERE id = 30;

然后单独地和稍后,其他人做一个:

代码语言:javascript
复制
DELETE FROM a WHERE id = 3;

如果要撤消第一个删除,它将失败,除非您首先撤消第二个删除。

基本上,只有按照首先发生的顺序撤消所有后续操作,才能可靠地撤消操作。即使如此,也很难纠正错误。

甚至在您开始考虑模式更改之前。如果将一个新的NOT NULL列添加到表中,那么要撤消在添加该列之前发生的DELETE,您要做什么?在列中给新行以默认值?如果没有DEFAULT集怎么办?

我会录制一个审计历史,但通常不会尝试支持撤销。

您可能希望研究PostgreSQL的实时恢复特性,以实现数据库范围的回滚或恢复到以前的点。

票数 4
EN

Database Administration用户

发布于 2013-06-25 19:19:09

你有几个选择:

  1. 通过编程,您可以使用命令模式†来实现撤销
  2. 在短时间内,您可以使用数据库事务,并回滚事务。
  3. 对于更长的时间范围,您可以使用http://en.wikipedia.org/wiki/Change_数据_俘获或“历史表”来跟踪已更改的内容,但您必须手动撤消更改。

http://mattberther.com/2004/09/16/using-the-command-pattern-for-undo-functionality

票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/45226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档