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

Я хочу сделать простую систему управления версиями, но у меня нет идей о том, как структурировать мои данные и мой код.

Вот краткий пример:

  1. Пользователь регистрируется в
  2. Пользователь имеет два варианта при загрузке файла:
    • Отправить новый файл
    • Отправить новую версию файла

Пользователи должны иметь возможность видеть дерево. (другая версия) Дерево может содержать только до двух уровней:

| |--File_A_0 \--File_A_1 \--File_A_2 \--File_A_3 \--File_A_4 

Существует также 2 типа файлов, окончательный (последний вариант) и черновик (последний загруженный файл). Файл будет физически сохранен на сервере. Каждый файл принадлежит пользователю (или более) и только одной группе.

Изменить: Группы представляют собой группу документов, документ может принадлежать только одной группе. Пользователи НЕ зависят от групп.

Начать редактирование:

Вот что я сделал, но это не очень эффективно!

 id_article | relative_group_id | id_group | title | submited | date | abstract | reference | draft_version | count | status id_draft | id_file | version | date 

Но его трудно справиться, расширить. Я думаю, это потому, что группа paramater …

Редактирование конца

Поэтому вопросы:

  • Как я могу схематизировать мою базу данных?
  • Какая информация должна быть полезной для выполнения этой работы?
  • Какая структура для папок, файлов?
  • Какие советы, подсказки, вы должны делать такую ​​работу?

(Приложение разработано с PHP и Zend Framework, база данных должна быть mysql или postgresql)

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

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

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

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

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

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


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

Что касается структуры базы данных, вы можете попробовать такую ​​структуру (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 позволяет связать нескольких пользователей с каждой версией документа.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Советы

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

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

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

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

Создание богатой структуры данных в традиционной реляционной базе данных, такой как 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, – поскольку вы получаете больше изменений и больше файлов, база данных будет становиться все больше и больше, таким образом вы можете пошатнуть изменения в нескольких файлах, сохранить резервные копии всего, сделать убедитесь, что у вас есть постоянные данные через интерфейсы и платформы и т. д.

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

Для схемы базы данных вам, вероятно, понадобятся два набора информации, файлы и версии файлов. Когда новый файл сохраняется, создается и начальная версия. Последняя утвержденная версия должна храниться явно, в то время как самая новая версия может быть выбрана из таблицы версий (либо путем поиска самой высокой версии, связанной с файлом, либо самой новой даты, если вы храните ее при их создании)

 files(id,name,approved_version) file_versions(id,fileId) 

версии файлов затем могут быть сохранены с использованием их идентификаторов (например, «/ fileId / versionId» или «/ fileId / versionId_fileName») на сервере с их исходным именем, хранящимся в базе данных.

Недавно я создал простую систему управления версиями для некоторых статических объектов данных. Требование состояло в том, чтобы иметь «активную» версию и 0 или 1 «ожидающие» версии.

В конце концов, мой объект с версией имел следующие атрибуты, относящиеся к управлению версиями.

VersionNumber (int / long) ActiveVersionFlag (boolean)

Где:-

  • только 1 объект может быть ActiveVersionFlag = 'Y'
  • только 1 объект может быть номером версии> «активной» версией (т.е. «ожидающей» версией)

Виды операций, которые я разрешил, были

Текущая версия Clone.

  • Ошибка, если уже есть версия> Номер версии версии «Активный»
  • Скопируйте все данные в новую версию
  • увеличить номер версии на один

Активировать ожидающую версию

  • Ошибка, если указанная версия не является «активной» версией + 1
  • найдите «активную» версию и установите для параметра ActiveVersionFlag значение «N»,
  • установите для параметра ActiveVersionFlag «ожидающей» версии значение «Y»

Удалить ожидающую версию

  • Удалить ожидающий объект

Это было достаточно успешно, и мои пользователи теперь клонируются и активируются все время 🙂

Майкл

Начните с существующей системы управления контентом , сделанной в PHP и MySQL, если это ваши требования, такие как eZ Publish или Knowledgetree . Для быстрого тестирования этих приложений Bitnami обеспечивает быструю установку « стеков » этих (WAMP-стеков на стероидах).

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

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

У сервера будет свой корневой каталог данных, и вы можете хранить группы (файлов) в папках с записью метаданных root в каждой папке. (Возможно, XML)?

Затем вы можете использовать существующий инструмент управления ревизией, завернутый в API, или сворачивать свой собственный, сохраняя изменения файлов в папке ревизий под элементом в папке. Проверьте наличие изменений и выполните ввод / вывод файлов с командами ввода / вывода файлов. Откройте API для веб-приложения или другого клиентского приложения и дайте серверу определять разрешения файлов и сопоставление пользователей через файлы XML.

Миграция серверов? Почтовый индекс и копия. Кросс-платформу? Почтовый индекс и копия. Резервное копирование? Почтовый индекс и копия.

Например, это плоский файл, который мне нравится в Mercurial DVCS.

Конечно, в этом маленьком примере файлы .rev могли иметь даты, время, сжатие и т. Д. И т. Д., Определенные в файле revisions.xml. Когда вы хотите получить доступ к одному из этих исправлений, вы обнаружите метод AccessFile (), который ваше серверное приложение будет искать в файле revisions.xml, и определите, как открыть этот файл, предоставлен ли доступ и т. Д.

Так что у тебя есть

 ДАННЫЕ
 |  + ROOT
 |  |  ,  metadata.xml
 |  |  |
 |  |  + ПЕРЕСМОТРЫ
 |  |  |  ,  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
 |  |  |  |
 |  |  |  + ПЕРЕСМОТРЫ
 |  |  |  |  ,  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
 |  |  | ___
 |  |
 |  | ___
 |
 | ___

Проверьте ProjectPier (первоначально ActiveCollab ). У этого есть система, подобная этому, и вы могли бы посмотреть на их источник.

Загрузка файлов – 1990-ty =) Посмотрите на Google Wave! Вы можете просто создать все свое приложение вокруг своей системы контроля версий.

Это не так просто, как кажется. Прочтите эту статью Эрика Синка о последствиях хранения этих файлов.

Возможно, лучшим вопросом будет то, какие файлы загружаются, и хорошо ли они подходят для управления версиями (например, текстовые файлы)

Я думаю, что это описывает идеальную систему для управления версиями

http://tom.preston-werner.com/2009/05/19/the-git-parable.html