Как закодировать простую систему управления версиями?

Ответов: 13


48 принят
+150

Ради Бога, не надо . Вы действительно не хотите идти по этой дороге.

Остановитесь и подумайте о большей картине на мгновение. Вы хотите сохранить более ранние версии документов, а это значит, что в какой-то момент кто-то захочет увидеть некоторые из этих ранних версий, верно? И тогда они собираются спросить: «В чем разница между версией 3 и версией 7»? И тогда они собираются сказать: «Я хочу вернуться к версии 3, но сохраните некоторые изменения, которые я внес в версию 5, ummm, ок?»

Управление версиями является нетривиальным, и нет необходимости изобретать колесо - есть много жизнеспособных систем контроля версий, некоторые из них бесплатные, даже.

В конечном счете, будет намного легче изучить API одной из этих систем и создать веб-интерфейс, который предлагает своим пользователям подмножество функций, которые они ищут (сейчас).

Вы бы не закодировали текстовый редактор для своих пользователей, не так ли?


18 ов

Вы можете получить вдохновение оттуда .


Относительно вашего комментария:

Что касается структуры базы данных, вы можете попробовать такую ??структуру (MySQL sql):

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`)
);

Документы являются логическим контейнером, а в Revisions содержатся фактические ссылки на файлы. Всякий раз, когда человек обновляет новый файл, создайте запись в каждой из этих таблиц, в редакторе, содержащей ссылку на тот, который вставлен в документы.

Таблица M2M_UserRev позволяет связать нескольких пользователей с каждой версией документа.

Когда вы обновляете документ, вставляйте только в Редакции, с добавлением к соответствующему документу. Чтобы узнать, к какому документу нужно подключиться, вы можете использовать соглашения об именах или попросить пользователя выбрать нужный документ.

Для архитектуры файловой системы ваших файлов это действительно не имеет значения. Я бы просто переименовал свои файлы в нечто уникальное, прежде чем они будут сохранены на сервере, и сохраните имя файла пользователя в базе данных. Просто сохраните файлы, переименованные в папку в любом месте, и сохраните путь к нему в базе данных. Таким образом, вы знаете, как переименовать его, когда пользователь запросит его. Вы также можете сохранить оригинальное имя, данное пользователем, если вы уверены, что оно будет уникальным, но я бы не стал слишком полагаться на него. Вскоре вы можете увидеть две разные версии с одним и тем же именем и одну перезапись другой в вашей файловой системе.


13

Схема базы данных


Чтобы это было очень просто, я бы выбрал следующий дизайн базы данных. Я разделяю концепт « файл » (такой же, как файл файловой системы) из концепции « документ » (gerarchic group of documents).

Пользовательский объект:

  • Идентификатор пользователя
  • имя_пользователя

Групповое лицо:

  • идентификатор_группы
  • Название группы

Сущность файла :

  • fileId (последовательность)
  • fileName (имя, которое пользователь дает файлу)
  • filesystemFullPath
  • uploadTime
  • uploaderId (идентификатор пользователя-загрузчика)
  • ownerGroupId

Объект документа :

  • documentId
  • parentDocumentId
  • FILEID
  • номер версии
  • CreationTime
  • одобрено

Каждый раз, когда загружается новый файл, создается запись «Файл», а также новый «Документ». Если это первый раз, когда файл загружен, parentDocumentId для этого документа будет NULL. В противном случае новая запись документа будет указывать на первую версию.

Поле isApproved (логическое) будет обрабатывать документ как черновик или одобренную ревизию.
Вы получаете последний черновик документа, просто заказывая нисходящий номер версии или время загрузки.

Советы


Из того, как вы описываете проблему, вы должны лучше анализировать эти аспекты, прежде чем переходить к схеме схемы базы данных:

  • которая является ролью «групповой» организации?
  • как связаны группы / пользователи / файлы?
  • что, если два пользователя разных групп попытаются загрузить один и тот же документ?
  • вам понадобятся папки? (возможно, вы будете: мое решение все еще действует, указывая тип, «папку» или «документ», на объект «документ»)

Надеюсь это поможет.


9

Может ли существующее решение по управлению версиями работать лучше, чем сворачивать ваши собственные? Subversion может быть сделано, чтобы сделать большую часть того, что вы хотите, и это прямо там.


6

Создание богатой структуры данных в традиционной реляционной базе данных, такой как MySQL, часто бывает затруднительным, и есть гораздо лучшие способы ее решения. При работе с структурой данных, основанной на путях с иерархией, мне нравится создавать плоскую файловую систему, которая использует формат сериализации данных, такой как JSON, для хранения информации о конкретном файле, каталоге или целом репозитории.

Таким образом, вы можете использовать текущие доступные инструменты, чтобы легко перемещаться и манипулировать структурой, и вы можете легко читать, редактировать и понимать структуру. XML тоже хорош для этого - он немного более подробный, чем JSON, но легко читается и хорош для обмена сообщениями и других систем на базе XML.

Быстрый пример. Если у нас есть репозиторий, в котором есть каталог и три файла. Глядя на нее спереди, она будет выглядеть так:

/repo
  /folder
    code.php
  file.txt
  image.jpg

У нас может быть папка метаданных, которая содержит наши файлы JSON, скрытые от ОС, в корне каждого каталога, которые описывают содержимое этого каталога. Вот как работают традиционные системы управления версиями, за исключением того, что вместо JSON используется пользовательский язык.

/repo
  */.folderdata*
  /code
    */.folderdata*
    code.php
  file.txt
  image.jpg

Каждая папка .folderdata может содержать собственную структуру, которую мы можем использовать для правильной организации данных папки. Каждая .folderdata папка может затем быть сжаты для экономии дискового пространства. Если мы посмотрим на папку .folderdata внутри каталога / code:

*/.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'
  }
}

Это позволяет нам связывать метаданные об этом файле, проверять подлинность и целостность, сохранять постоянные данные, указывать атрибуты файлов и делать гораздо больше. Затем мы можем сохранить информацию о конкретных версиях файла filerevisions.json:

{
  '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
    },
  ]
}

Это базовый план для системы управления версиями файлов - мне нравится эта идея и как она работает, и я использовал JSON в прошлом, чтобы отлично работать с такими богатыми структурами данных, как это. Подобные данные просто не подходят для реляционной базы данных, такой как MySQL, - поскольку вы получаете больше изменений и больше файлов, база данных будет становиться все больше и больше, таким образом вы можете пошатнуть изменения в нескольких файлах, сохранить резервные копии всего, сделать убедитесь, что у вас есть постоянные данные через интерфейсы и платформы и т. д.

Надеюсь, это дало вам некоторое представление, и, надеюсь, это принесет некоторую пищу для размышлений и для сообщества!

PHP, SQL, алгоритм, структуры данных, кода организация,
Похожие вопросы
Яндекс.Метрика