如何使用undo-redo设计SQL数据库?

bri*_*n h 10 mysql sql undo-redo audit-tables delta

我正在试图弄清楚如何设计我的数据库表以允许Undo-Redo.

假装您有一个具有以下结构的任务表:

id <int>
title <varchar>
memo <string>
date_added <datetime>
date_due <datetime>
Run Code Online (Sandbox Code Playgroud)

现在假设在几天内进行多次登录并进行了多次编辑; 但是用户想要回到其中一个版本.

  1. 您是否有一个单独的表来跟踪更改 - 或 - 您是否会尝试将更改保留在任务表中("ghost"行,因为缺少更好的术语)?
  2. 您会跟踪所有列还是每次更改的列?

如果重要,我正在使用MySQL.此外,如果重要,我希望能够显示历史记录(ala Photoshop)并允许用户切换到任何版本.

奖金问题:您是保存整个memo单元格的更改还是仅尝试保存delta?我问的原因是因为memo单元格可能很大,每个修订版本只能更改一个单词或字符.当然,保存delta需要解析,但如果不经常预期undos,那么节省空间而不是处理时间会不会更好?

谢谢您的帮助.

Adi*_*Adi 6

我会为你的任务表创建一个History表.与任务相同的结构+名为previousId的新字段.这将保留先前的更改ID,因此您可以通过不同的更改(撤消/重做)返回.

为什么要使用新的历史表?原因很简单:不要使用不是为其设计的东西来重载任务表.

至于空间,在历史记录中,使用二进制格式并压缩要存储的文本内容,而不是备忘录.不要试图检测变化.您将遇到一个错误的代码,这将导致沮丧和浪费时间......

优化:更好的是,您可以在历史记录表中只保留三列:1.taskId(任务的外键)2.数据 - 二进制字段.在保存在History表中之前,创建一个仅包含已更改字段的XML字符串.3. previousId(将帮助维护更改队列并允许来回导航)

对于数据字段,创建一个这样的XML字符串:

<task>
  <title>Title was changed</title>
  <date_added>2011-03-26 01:29:22<date_added>
</task>
Run Code Online (Sandbox Code Playgroud)

这基本上会告诉您,这次只更改了标题和date_added字段.

构建XML字符串后,如果需要,只需将其压缩并将其存储到History表的数据字段中.

XML还允许灵活性.如果在任务表中添加/删除字段,则也不需要更新历史记录表.因此,这种方式将tasks表和History表的结构解耦,因此您不需要每次都更新两个表.

PS:不要忘记添加一些索引以快速浏览历史表.要编制索引的字段:taskId和previousId,因为您需要对此表进行快速查询.

希望这可以帮助.