mysql - mysql 数据版本控制系统的最佳实践

标签 mysql database versioning

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

为了更好地理解,这里是基本表“文章”:

文章(ID、名称、文本)

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

方法 1

将文章的数据和每个版本存储在“文章”表中,并添加“版本”和“状态”列。在版本中,我存储文章的递增版本号。事件文章获取“状态”1,其他文章获取“状态”2。

专业人士:

  • 只需要一张 table

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

骗局

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

方法2

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

专业人士:

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

骗局

  • 表格复制

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

最佳答案

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

  • 您将每篇文章都插入到一个表中 articles_versioned (id时间戳、名称、文本)
  • 您的第二张 table 是 articles (id、时间戳、[名称、文本])。注意时间戳不是主要的;名称和文本可以复制,或者您可以使用 articles_versioned 的连接(这会很快,因为 id 和 timestamp 是 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"> 之类的内容。 ,您知道将永远可用。

关于mysql - mysql 数据版本控制系统的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17925435/

相关文章:

database - 即时数据的SQL分页

installation - 什么是使用嵌入式文件版本创建自解压可执行文件的好的免费实用程序?

ios - 使用 HockeyApp 将 iOS 版本限制为 < iOS 9

mysql - mysql 中的前导零

mysql - 过滤组合多列的重复项

sql - Informix SQL 查询 : Two similar queries returning different results

database - CakePHP 根据同一行中的其他值更新字段值?

java - 如何在mysql表中保存货币符号unicode

MySQL存储过程,错误: Result consisted of more than one row

tfs - checkin Team Foundation 时自动增加版本号