Php 如何编写一个简单的版本控制系统?

Php 如何编写一个简单的版本控制系统?,php,sql,algorithm,data-structures,code-organization,Php,Sql,Algorithm,Data Structures,Code Organization,我想做一个简单的版本控制系统,但我不知道如何构造数据和代码 下面是一个简短的例子: 用户登录 用户在上载文件时有两个选项: 提交新文件 提交文件的新版本 用户应该能够看到树。(不同版本) 树最多只能有两个级别: | |--File_A_0 \--File_A_1 \--File_A_2 \--File_A_3 \--File_A_4 还有两种类型的文件,一种是最终版本(即最新批准的版本),另一种是草稿版本(即最新上传的文件) 该文件将物理存储在服务器上。 每个文件都由一个(或多个)

我想做一个简单的版本控制系统,但我不知道如何构造数据和代码

下面是一个简短的例子:

  • 用户登录
  • 用户在上载文件时有两个选项:
    • 提交新文件
    • 提交文件的新版本
  • 用户应该能够看到树。(不同版本) 树最多只能有两个级别:

    |
    |--File_A_0
     \--File_A_1
     \--File_A_2
     \--File_A_3
     \--File_A_4
    
    还有两种类型的文件,一种是最终版本(即最新批准的版本),另一种是草稿版本(即最新上传的文件) 该文件将物理存储在服务器上。 每个文件都由一个(或多个)用户拥有,并且只有一个组

    编辑:组表示一组文档,文档一次只能由一个组拥有。用户不依赖于组

    开始编辑:

    这就是我所做的,但它不是真正有效的

    id_article | relative_group_id | id_group | title | submited | date | abstract | reference | draft_version | count | status
    
    id_draft | id_file | version | date
    
    但这很难管理,很难扩展。 我想这是因为这个团体的参数

    结束编辑

    因此,问题是:

    • 如何对数据库进行模式化
    • 什么样的信息应该是有用的 这部作品的版本
    • 这是一个什么样的结构 文件夹、文件
    • 你有什么建议和提示 做这种工作

    (应用程序是用PHP和Zend框架开发的,数据库应该是mysql或postgresql)

    你可能会从中得到启发


    关于您的评论:

    对于数据库结构,您可以尝试这种结构(MySQL sql):

    文档是一个逻辑容器,修订版包含到文件的实际链接。 每当有人更新新文件时,在每个表中创建一个条目,修订版中的条目包含指向文档中插入的条目的链接

    M2M_UserRev表允许将多个用户与文档的每个版本相关联

    更新文档时,仅在修订中插入,并与相应文档保持链接。要知道要链接到哪个文档,可以使用命名约定,或者要求用户选择正确的文档


    对于文件的文件系统体系结构来说,这真的无关紧要。在将文件存储到服务器上之前,我只需将其重命名为唯一的文件,并将用户文件名保留在数据库中。只需将重命名后的文件存储在任意文件夹中,并在数据库中保留其路径即可。这样,当用户请求时,您知道如何重命名它。如果您确信用户提供的原始名称是唯一的,那么您也可以保留它,但我不会太依赖它。您可能很快会看到两个不同的版本具有相同的名称,并且一个版本覆盖了文件系统中的另一个版本。

    签出(原始版本)。它有一个与此类似的系统,您可以查看它们的源代码。

    对于数据库架构,您可能需要两组信息,文件和文件版本。存储新文件时,也会创建初始版本。必须显式存储最新批准的版本,而可以从版本表中选择最新版本(通过查找与文件相关的最高版本或最新日期,如果您存储了文件的创建日期)


    然后,可以使用文件的ID(例如“/fileId/versionId”或“/fileId/versionId_fileName”)在服务器上存储文件版本,原始名称存储在数据库中

    上传文件是为了 看看谷歌浪潮!您可以围绕其“版本控制”框架构建整个应用程序。

    数据库模式

    为了保持非常简单,我会选择以下数据库设计。我将“文件”(与文件系统文件相同)概念与“文档”(gerarchic文档组)概念分开

    用户实体:

    • 用户ID
    • 用户名
    集团实体:

    • groupId
    • 组名
    文件实体:

    • fileId(一个序列)
    • 文件名(用户给文件的名称)
    • 文件系统完整路径
    • 上传时间
    • uploaderId(上传程序用户的id)
    • 所有者组ID
    文档实体:

    • documentId
    • parentDocumentId
    • fileId
    • 版本号
    • creationTime
    • 我同意
    每次上传一个新文件时,都会创建一个“文件”记录,以及一个新的“文档”。如果是第一次上载该文件,则该文档的parentDocumentId将为空。否则,新的文档记录将指向第一个版本

    “isApproved”字段(布尔值)将处理草稿或已批准修订的文档
    只需按版本号或上载时间降序即可获得文档的最新草稿

    提示

    根据您对问题的描述,在转到数据库架构设计之前,您应该更好地分析这些方面:

    • “集团”实体的角色是什么
    • 组/用户/文件的关系如何
    • 如果两个不同组的用户尝试上载同一个文档,该怎么办
    • 你需要文件夹吗?(您可能会这样做;我的解决方案仍然有效,为“文档”实体提供类型“文件夹”或“文档”)

    希望这能有所帮助。

    现有版本控制解决方案是否比您自己的版本控制解决方案更有效?Subversion可以做你想做的大部分事情,它就在那里。

    在传统关系数据库(如MySQL)中创建丰富的数据结构通常很困难,而且有更好的方法。当使用具有层次结构的基于路径的数据结构时,我喜欢创建一个基于平面文件的系统,该系统使用数据序列化格式(如JSON)来存储有关特定文件、目录或目录的信息
    CREATE TABLE `Users` (
           `UserID` INT NOT NULL AUTO_INCREMENT
         , `UserName` CHAR(50) NOT NULL
         , `UserLogin` CHAR(20) NOT NULL
         , PRIMARY KEY (`UserID`)
    );
    
    CREATE TABLE `Groups` (
           `GroupID` INT NOT NULL AUTO_INCREMENT
         , `GroupName` CHAR(20) NOT NULL
         , PRIMARY KEY (`GroupID`)
    );
    
    CREATE TABLE `Documents` (
           `DocID` INT NOT NULL AUTO_INCREMENT
         , `GroupID` INT NOT NULL
         , `DocName` CHAR(50) NOT NULL
         , `DocDateCreated` DATETIME NOT NULL
         , PRIMARY KEY (`DocID`)
         , INDEX (`GroupID`)
         , CONSTRAINT `FK_Documents_1` FOREIGN KEY (`GroupID`)
                      REFERENCES `Groups` (`GroupID`)
    );
    
    CREATE TABLE `Revisions` (
           `RevID` INT NOT NULL AUTO_INCREMENT
         , `DocID` INT
         , `RevUserFileName` CHAR(30) NOT NULL
         , `RevServerFilePath` CHAR(255) NOT NULL
         , `RevDateUpload` DATETIME NOT NULL
         , `RevAccepted` BOOLEAN NOT NULL
         , PRIMARY KEY (`RevID`)
         , INDEX (`DocID`)
         , CONSTRAINT `FK_Revisions_1` FOREIGN KEY (`DocID`)
                      REFERENCES `Documents` (`DocID`)
    );
    
    CREATE TABLE `M2M_UserRev` (
           `UserID` INT NOT NULL
         , `RevID` INT NOT NULL
         , INDEX (`UserID`)
         , CONSTRAINT `FK_M2M_UserRev_1` FOREIGN KEY (`UserID`)
                      REFERENCES `Users` (`UserID`)
         , INDEX (`RevID`)
         , CONSTRAINT `FK_M2M_UserRev_2` FOREIGN KEY (`RevID`)
                      REFERENCES `Revisions` (`RevID`)
    );
    
    files(id,name,approved_version)
    file_versions(id,fileId)
    
    /repo
      /folder
        code.php
      file.txt
      image.jpg
    
    /repo
      */.folderdata*
      /code
        */.folderdata*
        code.php
      file.txt
      image.jpg
    
    */.folderdata*
      /revisions
        code.php.r1
        code.php.r2
        code.php.r3
      folderstructure.json
      filerevisions.json
    
    {
      '.':        'code',
      '..':       'repo',
      'code.php': {
        'author_id': 11543,
        'author_name': 'Jamie Rumbelow',
        'file_hash': 'a26hb3vpq22'
        'access': 'public'
      }
    }
    
    {
      'code.php': [
        1: {
          'commit': 'ah32mncnj654oidfd',
          'commit_author_id': 11543,
          'commit_author_name': 'Jamie Rumbelow',
          'commit_message': 'Made some changes to code.php',
          'additions': 2,
          'subtractions': 4
        },
        2: {
          'commit': 'ljk4klj34khn5nkk5',
          'commit_author_id': 18676,
          'commit_author_name': 'Jo Johnson',
          'commit_message': 'Fixed Jamie\'s bad code!',
          'additions': 2,
          'subtractions': 0
        },
        3: {
          'commit': '77sdnjhhh4ife943r',
          'commit_author_id': 11543,
          'commit_author_name': 'Jamie Rumbelow',
          'commit_message': 'Whoah, showstopper found and fixed',
          'additions': 8,
          'subtractions': 5
        },
      ]
    }
    
    DATA | + ROOT | | . metadata.xml | | | | | + REVISIONS | | | . revisionsdata.xml | | | . documenta.doc.00.rev | | | . documenta.doc.01.rev | | | . documentb.ppt.00.rev | | | . documentb.ppt.03.rev | | |___ | | | | | . documenta.doc | | . documentb.ppt | | | | | + GROUP_A | | | . metadata.xml | | | | | | | + REVISIONS | | | | . revisionsdata.xml | | | | . documentc.doc.00.rev | | | | . documentc.doc.01.rev | | | | . documentd.ppt.00.rev | | | | . documentd.ppt.03.rev | | | |___ | | | | | | . documentc.doc | | | . documentd.ppt | | |___ | | | | | + GROUP_B | | | . metadata.xml | | |___ | | | |___ | |___