dav*_*wil 9 java database postgresql hibernate version
NB 我认为答案可能是以设计为中心的,因此基本上与实现无关,但如果有一些特别适合使用这些技术的解决方案,我将使用Java + Hibernate和Postgres.
我有一个包含特定字段的表格,它会包含大字符串,让我们说博客帖子平均为+10000个字符.
在我的应用程序中,您可以根据需要多次编辑博客帖子,并且在更新后将立即显示最新版本.但是,应用程序需要保留这些编辑的完整版本历史记录,以便查看它们.
一个明显的策略是保留一个单独的表,例如blog_post_history
,博客帖子行在创建时重复插入,每次后续更新到主"实时" blog_post
表,并带有递增的版本号,因此如果需要,这些版本都可用未来.我正在考虑使用像Hibernate Envers这样的东西进行设置.
然而,存储(和 - 可能更重要的是 - 传输),10000字符文本块的多个版本似乎非常低效,其中每个文本块之间的唯一区别可能是修复拼写错误,添加几个单词等.由于其性质对博客文章进行编辑时,可能会有许多像这样的小增量变化,而不是更少,更大的变化.
有没有更好的办法?
我正在考虑在编辑时仅存储当前版本和先前版本之间的增量,然后在请求时以编程方式从这些增量重建版本历史记录,可能在客户端上,因此通过网络发送的数据是最小化.
我很可能将最新版本存储为全文,因为我想优化请求最频繁,然后存储从当前版本向后的增量链,以便在请求它们时重建历史版本.
我现在正在研究的解决方案到目前为止运行良好,实现了我在问题中提出的设计
我正在考虑在进行编辑时仅存储当前版本和先前版本之间的增量,然后在请求时以编程方式从这些增量重建版本历史记录,也许在客户端上,因此通过线路发送的数据是最小化。
我很可能将最新版本存储为全文,因为我想针对最频繁的请求进行优化,然后存储从当前版本向后追溯的增量链,以在请求时重建历史版本。
我将在这里分享我的实施细节
为了创建增量并使用它来重建全文,我使用了很棒的google-diff-match-patch 库。您可以阅读与实现无关的API 文档,以更好地理解下面的代码示例,尽管它无论如何都非常可读。
google-diff-match-patch具有 Java 和 JS 实现,因此我可以使用它在服务器上使用 Java 计算增量。我选择将每个增量转换为字符串,这样它既可以轻松存储在数据库中,又可以轻松地被客户端上的 JS 库使用。下面详细介绍这一点。
public String getBackwardsDelta(String editedBlogPost, String existingBlogPost) {
diff_match_patch dmp = new diff_match_patch();
LinkedList<diff_match_patch.Patch> patches =
dmp.patch_make(editedBlogPost, existingBlogPost);
return dmp.patch_toText(patches);
}
Run Code Online (Sandbox Code Playgroud)
注意,我花了一段时间才弄清楚如何使用 Maven 来下载google-diff-match-patch的官方版本。它不在 Maven 中央存储库中,而是在 googlecode.com 上他们自己的存储库中。只是要注意,有些人已经分叉了它并将他们的分叉版本放在 Maven Central 中,但如果您确实想要官方版本,您可以通过在您的文件中添加存储库和依赖项来获得,pom.xml
如下所示
<repository>
<id>google-diff-patch-match</id>
<name>google-diff-patch-match</name>
<url>https://google-diff-match-patch.googlecode.com/svn/trunk/maven/</url>
</repository>
<dependency>
<groupId>diff_match_patch</groupId>
<artifactId>diff_match_patch</artifactId>
<version>current</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
对于前端,我传递最新的博客文章全文,以及代表每次编辑的时间倒退的增量链,然后在浏览器中用 JS 重建每个版本的全文。
为了获取该库,我使用 npm + browserify。该库在 npm 上以diff-match-patch形式提供。版本 1.0.0 是唯一的版本。
getTextFromDelta: function(originalText, delta) {
var DMP = require('diff-match-patch'); // get the constructor function
var dmp = new DMP();
var patches = dmp.patch_fromText(delta);
return dmp.patch_apply(patches, originalText)[0];
}
Run Code Online (Sandbox Code Playgroud)
就是这样,它的效果非常好。
在存储博客文章的编辑方面,我只使用一个表BLOG_POST_EDITS
来存储博客文章 ID、编辑时的时间戳(稍后我用它来正确排序编辑,以便在重建完整内容时创建链) -客户端上的文本版本),以及表中当前实时博客文章BLOG_POST
与传入的博客文章编辑版本之间的向后增量。
我选择存储增量“链”,因为它非常适合我的用例,并且在服务器代码端更简单。这确实意味着为了重建 N 的版本 M,我必须向客户端发送一条 N-(M-1) 增量链,从实时博客文章全文返回到版本 M。但在我的用例中,我碰巧无论如何,每次都想发送整个链,所以这很好。
为了在请求特定版本时获得更好的线上效率,每次进行编辑时,可以将所有增量从新编辑的博客文章版本重新计算回每个(恢复的)版本,但这意味着更多的工作和复杂性。服务器。
归档时间: |
|
查看次数: |
674 次 |
最近记录: |