我必须将文章等数据存储到 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
表。
这种方法的优点是:
- 您可以在表格中免费获得其他可能需要的信息(文章的日期和时间)
- 您无需查询数据库即可获取当前日期。如果您使用版本,则必须这样做。
- 您的代码不必在两个表格中插入文章。您只需插入
articles_versioned
并从articles
中读取,数据库会在您通过触发器插入数据时负责迁移数据,从而避免任何一致性问题。
骗局
- 在高度并发的环境中,可能会同时插入两个版本,因此其中一个可能会失败。在插入用户撰写的文章时,这应该不是问题(考虑到如今时间戳的精度,这极不可能)。如果您没有在
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/