捕获实体状态事务

时间:2017-07-20 04:39:44

标签: php mysql backup api-design database-backups

我有一个与运行php和mysql的API通信的应用程序。 我想要做的是记录每个用户在我的表中的实体发生的更改。如果用户对其数据进行了更改,我可以看到发生的更改。这样,如果他们有问题或意外删除某些内容,我可以回过头来告诉他们一年中不同阶段的实体是什么样的。

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

基本上我现在所做的是,对于某些路由,我的API会发生POST / PUT,我只需要在请求体中使用JSON,然后将其保存到数据库中的记录中作为发生的事务对于那个用户。

这在早期很棒,但是在成千上万的记录之后,JSON的体积很大,占据了很大的空间。我的数据库表是13GB。查询也需要一段时间才能运行。我把它截断了,但在4个月内它再次增长到10GB。这个问题可能会变得更大。

是否有人建议记录此方法?我是否可以将请求正文发送到AWS上的某些内容或脱机的其他存储或其他位置的其他数据库?可能是平面文件还是非关系型数据库?这并不像我实际需要实时数据,但如果我想得到一个我想知道的人的历史。

我确实需要每晚备份数据库,所以另一种方法是我正在考虑完全删除事务日志,而只是让它继续每晚备份。当然,我无法显示实体更新/添加日期的历史记录,但至少我总是可以参考一些备份,以查看在我执行某个特定日期后给定用户的记录还原

有任何想法或建议吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您可以只记录已更改的值,而不是记录整个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>
&#13;
&#13;
&#13;

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

您当然需要移植此PHP或查看可能满足您需求的某些现有软件包,例如node-rus-diff

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

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

最后,您可以完整备份并清除之前的交易,类似于完整备份。

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