4

我正在寻找一个系统来跟踪 Google App Engine (Python) 上 ndb.Models/Expandos 内容的版本(历史)。

内容可能比较长,可能有很多版本,但版本之间的差异可能很小。我希望其他人已经做过类似的事情,我想知道他们是如何做到的,以及哪些原则可以指导设计和开发。

在部署时不知道数据模型的属性是什么(例如“标题”、“内容”、“正文”、“日期”等),但类型是已知的(日期、文本、 ETC)。

我最初的想法是安排这样的事情:

from google.appengine.ext import ndb

class Version(ndb.Expando):
  version_id = ndb.IntegerProperty()
  # dated, etc.
  # data properties are not known in advance, hence Expando

 class MyDoc(ndb.Model):
   head     = ndb.KeyProperty(kind=Version)

   instance = ndb.kind=Property(kind=Version, repeated=True)
   # ^^^ may be a StructuredProperty?

算法概述如下:

保存

每次用户保存文档时,将所有最新数据放入一个新数据Version并指向head该实例。

到那时,或之后的某个时间,浏览旧版本并将完全保存更改为差异(以节省空间),例如diff-match-patch。我希望每小时、每天或某个设定时间或某个设定数量的差异进行一次完整的保存。

正在加载

加载head是微不足道的。

旧版本将被标记为完全保存或差异,并且取决于可以直接返回或从差异编译的数据。

想法?

我相信其他人已经解决了这个问题,我很想知道关于它的想法和实现。显然,有完整的版本控制系统,例如 Git、Mercurial 和 Subversion 以及 CVS——但这些系统对于预期目的来说都是多余的,并且无法在 Google App Engine 上运行。

4

1 回答 1

2

一些想法:

  • 您需要一个单调递增的版本 ID,因此您可以对版本实体进行范围查询。这可能意味着您需要将所有历史数据与文档放在同一实体组中,并在文档实体或同一组中的单独实体中保留最新版本 ID。如果您想要一个系统范围内单调递增的 ID(例如关联或排序对不同组中的多个实体所做的更改),您将需要查看分片计数器和跨组事务。

  • 如果空间足以让您担心存储差异,我不明白为什么您会将完整版本减少为具有后台作业的差异,而不仅仅是更新。如果空间不是一个大问题并且主要功能是能够区分两个任意版本,那么存储完整数据可能会更容易,因此差异的成本与中间版本的数量(或所有版本,如果您的差异在历史版本之间)。假设您不想对过去版本的属性执行查询,您可以通过以紧凑​​形式序列化旧实体并将其存储在非索引 blob 属性中来节省空间。(我假设这就是您存储每个差异的方式,如果您使用差异?)您还可以在每 n 次修订的里程碑中保留完整的文档,

  • 从您的描述看来,您更希望 MyDoc 成为对 Version 实体的引用,该实体将包含最重要的数据。也许 MyDoc 更容易包含最重要的数据(并使用 MyDoc 键等对其属性进行索引),并且更新只是使用以前的数据(差异或完整)创建版本。

  • 不要忘记容纳删除。也许 MyDoc 消失了(因此它不会出现在键和属性查询中),并且父路径的最新版本包含完整的最后一个已知文档。

(这只是我的想法。我对我工作的 CMS 进行了一些思考,但我还没有构建它。)

于 2012-05-16T21:31:20.403 回答