捕获实体状态交易

Capturing Entity State Transactions

我有一个应用程序可以与我的 API、运行、php 和 mysql 通信。 我想做的是为每个用户在我的 table 中记录实体发生的更改。如果用户更改了他们的数据,我可以看到发生的更改。这样,如果他们有任何疑问或不小心删除了某些内容,我可以返回并告诉他们这些实体在一年中的各个阶段是什么样子的。

我不需要疯狂地具体说明差异,我想做的就是记录插入或更新(因为它在 JSON 正文中表示)。

基本上我现在所做的是在某些路由的 API 出现 POST/PUT 时,我只是在请求正文中获取 JSON,然后保存它数据库中的记录作为该用户发生的事务。

这在早期是很棒的,但是经过数十万条记录后,JSON 正文很大并且占用了很多空间。我的数据库 table 是 13GB。查询也需要一段时间才能达到 运行。我 t运行 对其进行了处理,但在 4 个月内它再次增长到另一个 10GB。这个问题可能只会变得更大。

有没有人可以推荐一种方法来记录这个?我可以将请求正文发送到 AWS 上的某些内容或其他离线存储或其他地方的另一个数据库吗?可能是平面文件还是非关系数据库?这并不是说我真的需要实时数据,但如果我想获得某个人的历史,我想知道我可以。

我每晚都会对数据库进行备份,所以另一种方法是我考虑完全删除事务日志,而不是让它继续每晚备份。当然,我无法显示实体 updated/added 日期的历史记录,但至少我总是可以参考一些备份来查看给定用户在特定日期的记录恢复。

有什么想法或建议吗?谢谢!

无需记录整个 JSON,您可以只记录已更改的值,您也不必记录插入数据,因为您的数据库将始终具有当前记录并记录插入数据冗余。

您可以实施 Diff 函数来比较现有 JSON 与更改后的 JSON 的差异。

为了说明示例,请参阅下面的代码,该代码从 Answer.

中借用了 JavaScript Diff 函数

// get the current value from your database
var oldvalues = {
  "id": 50,
  "name": "Old Name",
  "description": "Description",
  "tasks": [{
    'foo': 'bar'
  }]
};
var newvalues = {
  "id": 50,
  "name": "New name",
  "description": "Description",
  "tasks": [{
    'foo': 'bar'
  }]
};

var isEmptyObject = function(obj) {
                    var name;
                    for (name in obj) {
                        return false;
                    }
                    return true;
                };


 var diff = function(obj1, obj2) {
                    var result = {};
                    var change;
                    for (var key in obj1) {
                        if (typeof obj2[key] == 'object' && typeof obj1[key] == 'object') {
                            change = diff(obj1[key], obj2[key]);
                            if (isEmptyObject(change) === false) {
                                result[key] = change;
                            }
                        }
                        else if (obj2[key] != obj1[key]) {
                            result[key] = obj2[key];
                        }
                    }
                    return result;
                };

var update = diff(oldvalues, newvalues);
//save this to your database

$('#diff').text(JSON.stringify(update));
textarea {
  width: 400px;
  height: 50px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<textarea id="diff"></textarea>

如您所见,唯一可以保存的更改是 {"name":"New name"},这将减少您的数据使用量。

你当然需要移植这个 PHP 或查看一些现有的包,例如 node-rus-diff 可能会满足您的需求。

只要保留时间戳或序列号,就可以链接多个事务以回滚到任何先前状态。这类似于进行增量备份。

如果您想创建检查点并将当前状态与以前的状态进行比较,您还可以 运行 以设定的时间间隔执行维护任务。也许每月一次备份并记录已更改的对象之间的差异。这类似于差异备份。

最后,您可以进行完整备份并清除之前的事务,类似于完整备份。

管理员通常会结合使用增量备份、差异备份和完整备份来平衡存储成本和恢复需求。使用上面概述的这些方法,您可以实施适合您的策略。