Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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


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

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

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

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

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

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

Ответ 3

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


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

Пользователь:

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

Группа:

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

Файл:

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

Документ:

  • documentId
  • parentDocumentId
  • FILEID
  • VersionNumber
  • CreationTime
  • isApproved

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

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

Советы


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

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

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

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

Ответ 7

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

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

Номер версии (int/long) ActiveVersionFlag (boolean)

Где: -

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

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

Текущая версия клона.

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

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

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

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

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

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

Майкл

Ответ 8

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

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

Ответ 9

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

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

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

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

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

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

Итак, у вас есть

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
| | |___
| |
| |___
|
|___

Ответ 10

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

Ответ 11

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

Ответ 12

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

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