13

我必须将文章之类的数据存储到 mysql 数据库中,如果文章被修改,我还必须保存旧版本以使其可以恢复。我在这个主题上发现了一些类似的问题和帖子,但我不确定,哪种解决方案最能解决这个问题。

这是基本表“文章”,以便更好地理解:

文章(id,名称,文本)

对我来说,有两种不同的方法:

方法一

将文章的数据和每个版本存储在“articles”表中,并添加“version”和“status”列。在版本中,我存储文章的递增版本号。活动文章获得“状态”1,其他文章获得“状态”2。

专业人士:

  • 只需要一张桌子

  • 新版本是新数据的插入,只是旧数据的“状态”列的更新

骗局

  • 非常大的表(可能查询速度较慢???)

方法二

将字段“版本”添加到“文章”中,并且仅将活动数据存储到“文章”表中。旧版本的数据存储/移动到新表“articles_versioned”。

专业人士:

  • 只有实际有效数据在“文章”表中

骗局

  • 表的复制

所以。我忘记了一个好的方法吗?如何处理其他表中的相关数据(如图片等)?

4

1 回答 1

17

我的选择是方法 2 的变体。粗体表示主键中的字段。

  • 您将每篇文章插入到表中articles_versionedidtimestamp、name、text)
  • 您的第二个表是articlesid,timestamp,[name,text])。注意时间戳不是主要的;可以复制名称和文本,或者您可以使用连接articles_versioned(这会很快,因为 id 和时间戳是articles_versioned主键)
  • articles_versioned在插入上有一个触发器,它采用刚刚插入的行并将其复制到articles
  • 要恢复文章的特定版本,您需要修改articles表。

这种方法的优点是:

  1. 您可以在表格中免费获得另一个信息(文章的日期和时间),无论如何您都可能需要这些信息
  2. 您无需查询数据库即可获取当前日期。如果你使用版本,你必须。
  3. 您的代码不必在两个表中插入文章。您只需插入articles_versioned并从中读取articles,数据库会在您通过触发器插入数据时负责迁移数据,从而避免任何一致性问题。

骗局

  1. 在高度并发的环境中,可能会同时插入两个版本,因此其中一个可能会失败。在插入用户撰写的文章时,这应该不是问题(考虑到如今时间戳的精度,这极不可能)。如果您没有在INSERT语句中指定时间戳,而是将 datetime 字段设置为将当前时间作为默认值,则可以完全避免此问题。

回答你的其余问题。只要您在状态上添加索引,方法 1 就不会导致更长的查询。仅当您倾向于拥有每篇文章的许多不同版本时,这才有意义;只要您平均每篇文章有 2 个版本或更少,索引只会减慢您的速度,而且方法 2 无论如何也不会明显更快(尽管我仍然推荐我的方法,因为它简化了代码,因为恢复版本确实不需要两行的切换状态)。

相关资源(如图像)应遵循类似的版本控制。我假设您将它们保存在文件系统上;不要用他们的真实姓名保存它们,而是使用一个表(id, image_name )给每个图像一个 id,然后将图像保存为-id-.jpg. image_name 字段将使您能够知道原始文件名是什么(如果您关心的话)。通过这种方式,您可以以与版本文章相同的方式来版本图像,并且在文章中您会使用类似的东西<img src="-id-.jpg">,您知道这些东西将永远可用。

于 2015-05-06T09:07:10.520 回答