ale*_*ods 6 mysql sql database postgresql
保持数据库中某些实体的更新(差异)的最佳方法是什么?在 StackOverflow,我们可以编辑问题和答案。然后我们可以查看我们想要的问题或答案的任何修订。例如: 修改一些随机问题。也许有人知道它在 StackOverflow 中是如何实现的?
需要明确的是,在我的例子中,我有一些实体 ( article) 和一些字段 ( name, description, content) 。许多用户可以编辑同一篇文章。我想保留文章更新的历史记录(类似于版本控制),并且我想仅保留差异,而不是更新文章的全部内容。顺便说一句,我使用 PostgreSQL,但可以迁移到任何其他数据库。
UPD 开放赏金,所以这里有一些要求。你不需要完全满足他们。但如果你这样做的话,效果会好很多。尽管如此,我们非常感谢任何答案。所以我想拥有一种能力:
header、description或content(如 StackOverflow 的标题和内容会发生变化),因此必须考虑到这一点。过去,我使用diff-match-patch获得了出色(且快速)的结果。它可用于多种语言(我的经验是使用 C#)。我没有将它用于您所描述的确切过程(我们对合并感兴趣),但在我看来您可以:
如果您想加快速度,可以将文章的最新版本缓存在其自己的行/表/但是您组织的事物中,以便通过简单的 SELECT 获取最新版本。这样,您就可以获得初始版本、补丁列表和当前版本,从而为您提供一定的灵活性和速度。
由于您有一组按顺序的补丁,因此获取文章的任何版本只需将补丁应用到所需的补丁即可。
您可以查看补丁演示,了解其补丁的外观并了解它们有多大。
就像我说的,我还没有将它用于这种情况,但 diff-match-patch 的设计目的或多或少正是您所说的。当我对外部开发的库没有限制时,这个库就在我可以使用的软件的简短列表中。
例如,您可以像这样设置表(这假设还有一些其他表,例如作者):
Articles
--------
id
authorId
title
content
timestamp
ArticlePatches
--------------
id
articleId
patchText
timestamp
CurrentArticleContents
----------------------
id
articleId
content
Run Code Online (Sandbox Code Playgroud)
那么一些基本的 CRUD 可能如下所示:
插入新文章:
INSERT INTO Articles (authorId, title, content, timestamp)
VALUES(@authorId, @title, @content, GETDATE())
INSERT INTO CurrentArticleContents(articleId, content)
VALUES(SCOPE_IDENTITY(),@content)
GO
Run Code Online (Sandbox Code Playgroud)
获取包含最新内容的所有文章:
SELECT
a.id,
a.authorId,
a.title,
cac.content,
a.timestamp AS originalPubDate
FROM Articles a
INNER JOIN CurrentArticleContents cac
ON a.id = cac.articleId
Run Code Online (Sandbox Code Playgroud)
更新文章内容:
//this would have to be done programatically
currentContent =
(SELECT content
FROM CurrentArticleContents
WHERE articleId = @articleId)
//using the diff-match-patch API
patches = patch_make(currentContent, newContent);
patchText = patch_toText(patches);
//setting @patchText = patchText and @newContent = newContent:
(INSERT INTO ArticlePatches(articleId, patchText, timestamp)
VALUES(@articleId, @patchText, GETDATE())
INSERT INTO CurrentArticleContents(articleId, content, timestamp)
VALUES(@articleId, @newContent, GETDATE())
GO)
Run Code Online (Sandbox Code Playgroud)
获取特定时间点的文章:
//again, programatically
originalContent = (SELECT content FROM Articles WHERE articleId = @articleId)
patchTexts =
(SELECT patchText
FROM ArticlePatches
WHERE articleId = @articleId
AND timestamp <= @selectedDate
ORDER BY timestamp ASCENDING)
content = originalContent
foreach(patchText in patchTexts)
{
//more diff-match-patch API
patches = patch_fromText(patchText)
content = patch_apply(patches, content)[0]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1393 次 |
| 最近记录: |