我正在开发一个基于Web的Java项目,它将最终用户数据存储在MySql数据库中。我想实现一些允许用户具有与我的源代码版本控制(例如Subversion)类似的功能的东西。换句话说,我想实现允许用户提交和回滚工作并返回现有分支的代码。是否有现有的框架?似乎将数据库数据放入版本控制并向最终用户公开版本控制功能(即允许用户提交,回滚等的编写代码)可能是一种合理的方法,但它似乎也可能是一些问题用这种方法。例如,您如何允许一个用户查看数据的回滚版本(即,如果一个用户想要查看数据的回滚版本,您不能只替换数据库指向的数据)?如果可以选择使用任何持久性体系结构完全重建系统,那么可以用来存储使这类功能易于实现的数据?
答案 0 :(得分:3)
有两种非常常见的解决方案可满足您的需求:
答案 1 :(得分:1)
您的问题是关于在应用程序中对用户数据进行版本化的解决方案,以便为您的用户提供分支和合并等功能。你考虑过暴露一个真正的版本控制,比如svn。
我可以预见的副作用是:
版本控制工作副本将仅限于使用" ="的主键查询。操作员和顺序扫描。这还不足以对我能想到的任何使用模式做出好的报告和统计。这就是您需要从应用程序数据构建数据集市的原因,并且您有两种方法:
批处理更容易实现,但报告和统计信息需要时间与活动同步。您可能希望在1.0版本中采用这种方式,并及时转向触发器以使事物更具动态性。
GIT,SVN和CVS支持在提交新版本时执行程序的触发器。然后可以检查关系和一致性以接受或不接受更改。
由于您没有指定所需的应用程序类型,我将讨论博客,内容门户和在线商店。对于那些类型的应用程序,我认为没有太多理由重新发明轮子并构建自定义数据库。大多数必要的版本控制都可以在数据库模型中预测。一个好的面向事件的数据库设计就足够了。
例如,博客文章中的修订版可以建模为标记帖子的结束日期/时间并为修订后的帖子创建新行,增加版本号并设置以前的版本ID。相同的策略可以与在线商店的销售和目录一起使用。如果使用良好的日志为应用程序建模,则不需要版本控制。
一些开发人员还会执行行级触发器,记录数据库中已更改的所有内容。对于需要从错误设计的日志重建过去的审计员来说,这有点困难。我个人不喜欢这种方式,因为很难索引这类查询。我更喜欢将我的整个应用程序围绕一个设计良好且有意义的日志。
例如:
History Table
10/10/2010 [new process] process_id=1; name=john
11/10/2010 [change name] process_id=1; old_name=john; new_name=john doe
12/10/2010 [change name] process_id=1; old_name=john doe; new_name=john doe junior
Process Table after 12/10/2010.
proc_id=1 name=john doe junior
通过这种方式,我可以重建过去的几乎所有内容,并且仍然以易于使用的格式提供我的操作数据。
但是,这并不接近您想要的使用模式(分支和合并)
版本控制作为数据库的适用性一方面在我看来非常强大,另一方面非常有限和危险。它对于审计和纠错目的非常鼓舞人心。但我主要担心的是规模和可靠性。
答案 2 :(得分:-1)
你提到了Subversion,它是一个集中版本控制系统。但是,由于原因,让我们专注于Git。 Git是一个分散版本控制系统。如果存在远程副本(GitLab和GitHub等服务提供远程外壳和管理Git项目),Git存储库的本地副本与存储库的远程副本相同。使用Git,您可以在计算机的任意目录中进行版本控制。您可以在此任意目录中执行您习惯使用SVN的任何操作,等等。
我得到的是,您可以通过编程方式在服务器中创建每个用户目录/存储库,并在这些目录/存储库中应用版本控制,为每个用户保留一个单独的存储库(将确定架构的细节)但是,稍后,取决于用户的“工作”的结构。您的应用程序将负责代表用户添加和删除文件(例如,传记,我的示例项目等),编辑文件,提交更改,呈现文件历史记录等,基本上发布Git命令。因此,您的应用程序将与Git存储库连接,利用Git提供的高级版本控制。您的数据库只会确保用户链接到包含其“工作”的目录/存储库。
为了提供一个关键的类比,GitLab项目是一个基于Web的开源Git存储库管理器,具有维基和问题跟踪功能。 GitLab是用Ruby编写的,并使用PostgreSQL(最好)。它是典型的(如代码 - 数据库 - 数据目录和文件中)多用户基于Web的应用程序。其目的是管理Git存储库。这些Git存储库存储在服务器的指定目录中。部分代码负责访问登录用户有权访问的Git存储库(作为所有者或协作者)。一个有趣的用例是用户在线编辑文件,这将导致某些存储库中某个分支的提交。另一个有趣的用例是用户检查文件的历史记录。最后一个有趣的用例是用户恢复特定提交。所有这些操作都是通过网络浏览器在线执行的。
为了提供一个有趣的实际用例,O'Reilly的Atlas是一个使用GitLab作为后端进行出版相关协作的在线平台。
对于Java,有JGit,一个实现Git版本控制系统的轻量级纯Java库。 Eclipse使用JGit进行与管理Git存储库相关的所有操作。也许你可以调查一下。这是一个非常活跃的项目,由许多人支持。
以上所有内容都有意义,如果您引用的“工作”不仅仅是数据库表中的某些字段,用户将填写这些字段,以后可能会更改其值。例如,它对结构化文本,HTML等有意义。
如果这个“工作”不是那么大规模,那么做一些类似于上面描述的事情就是矫枉过正。在这种情况下,您可以在数据库设计中使用一些版本控制概念,例如计算差异和应用补丁(反过来,用于查看过去的版本/回滚)。你的表应该允许树状结构,以存储差异,所以你可以允许分支。您可以随时使用文件的活动版本,以及活动索引(Git调用HEAD),并通过顺序应用所有补丁(如果向前移动)导航到文件历史记录中的另一个索引/散列/标记版本,或者如果向后移动,则以相反的时间顺序应用补丁。如果这个“工作”真的是小规模的,你甚至可以放弃差异概念,并将整个版本的“工作”存储在树状结构中。
纯粹的乐趣。