php - sgc - procedimiento de control de documentos iso 9001:2015
¿Cómo codificar un sistema de control de versiones simple? (13)
¿Podría una solución de control de versiones existente funcionar mejor que la suya? Se puede hacer que Subversion haga la mayor parte de lo que desea y está ahí.
Quiero hacer un sistema de control de versiones simple, pero no tengo ideas sobre cómo estructurar mis datos y mi código.
Aquí hay un pequeño ejemplo:
- El usuario inicia sesión
- El usuario tiene dos opciones cuando carga un archivo:
- Presentar un nuevo archivo
- Presentar una nueva versión de un archivo
Los usuarios deberían poder ver el árbol. (la versión diferente) El árbol solo puede tener hasta 2 niveles:
|
|--File_A_0
/--File_A_1
/--File_A_2
/--File_A_3
/--File_A_4
También hay 2 tipos de archivo, un final (que es la última versión aprobada) y una versión en borrador (que es el último archivo cargado). El archivo se almacenará físicamente en el servidor. Cada archivo es propiedad de un usuario (o más) y solo un grupo.
Editar: los grupos representan un grupo de documentos, el documento solo podría ser propiedad de UN grupo a la vez. Los usuarios NO dependen de grupos.
Comience la edición:
Esto es lo que hice, ¡pero no es realmente eficiente!
id_article | relative_group_id | id_group | title | submited | date | abstract | reference | draft_version | count | status
id_draft | id_file | version | date
Pero es difícil de gestionar, extender. Creo que es porque el grupo paramater ...
Finalizar edición
Entonces las preguntas son:
- ¿Cómo puedo esquematizar mi base de datos?
- ¿Qué tipo de información debería ser útil para la versión de este trabajo?
- ¿Qué tipo de estructura para las carpetas, archivos?
- ¿Qué tipo de consejos, sugerencias tienes que hacer este tipo de trabajo?
(La aplicación se desarrolla con PHP y Zend Framework, la base de datos debe ser mysql o postgresql)
Comience desde un sistema de gestión de contenido existente, hecho en PHP y MySQL, si esos son sus requisitos, como eZ Publish o Knowledgetree . Para realizar pruebas rápidas de estas aplicaciones, Bitnami también proporciona " stacks " rápidos de instalación (WAMP-stacks con esteroides).
Luego puede adaptar estas aplicaciones a las necesidades de su organización y mantenerse actualizado con los cambios en la etapa inicial.
Como alternativa a mi publicación anterior, si cree que una estructura jerárquica sería la mejor, puede usar almacenamiento de archivos planos y exponer una API a través de un servicio web.
El servidor tendría su directorio raíz de datos y usted puede almacenar grupos (de archivos) en carpetas, con una entrada de metadatos raíz en cada carpeta. (XML tal vez?)
Luego puede usar una herramienta de control de revisiones existente envuelta en una API, o hacerla suya, manteniendo las revisiones de los archivos en una carpeta de revisiones debajo del elemento en la carpeta. Verifique las revisiones y realice E / S de archivos con los comandos de E / S de archivos. Exponga la API en la aplicación web u otra aplicación cliente y deje que el servidor determine los permisos de archivos y la asignación de usuarios a través de los archivos XML.
¿Migrar servidores? Zip y copia ¿Plataforma cruzada? Zip y copia ¿Apoyo? Zip y copia
Es el backend de archivos planos que me encanta de Mercurial DVCS, por ejemplo.
Por supuesto, en este pequeño ejemplo, los archivos .rev pueden tener fechas, tiempos, compresión, etc., definidos en el archivo revisionions.xml. Cuando desee acceder a una de estas revisiones, expondrá un método AccessFile (), que su aplicación de servidor verá en el archivo revisionions.xml, y determinará cómo abrir ese archivo, si se concede acceso, etc.
Así que tienes
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 | | |___ | | | |___ | |___
Crear una estructura de datos enriquecida en una base de datos relacional tradicional como MySQL a menudo puede ser difícil, y hay formas mucho mejores de hacerlo. Cuando trabajo con una estructura de datos basada en rutas con una jerarquía, me gusta crear un sistema basado en archivos planos que utiliza un formato de serialización de datos como JSON para almacenar información sobre un archivo específico, directorio o un repositorio completo.
De esta forma, puede usar las herramientas disponibles actualmente para navegar y manipular la estructura fácilmente, y puede leer, editar y comprender la estructura fácilmente. XML también es bueno para esto: es un poco más detallado que JSON pero fácil de leer y también es útil para mensajería y otros sistemas basados en XML.
Un ejemplo rápido Si tenemos un repositorio que tiene un directorio y tres archivos. Mirándolo de frente se verá así:
/repo
/folder
code.php
file.txt
image.jpg
Podemos tener una carpeta de metadatos, que contiene nuestros archivos JSON, ocultos desde el sistema operativo, en la raíz de cada directorio, que describen los contenidos de ese directorio. Así es como funcionan los sistemas de control de versiones tradicionales, excepto que usan un lenguaje personalizado en lugar de JSON.
/repo
*/.folderdata*
/code
*/.folderdata*
code.php
file.txt
image.jpg
Cada carpeta .folderdata puede contener su propia estructura que podemos usar para organizar los datos de la carpeta correctamente. Cada carpeta .folderdata podría comprimirse para ahorrar espacio en el disco. Si miramos la carpeta .folderdata dentro del directorio / code:
*/.folderdata*
/revisions
code.php.r1
code.php.r2
code.php.r3
folderstructure.json
filerevisions.json
La estructura de la carpeta define la estructura de nuestra carpeta, donde los archivos y las carpetas están en relación entre sí, etc. Esto podría verse más o menos así:
{
''.'': ''code'',
''..'': ''repo'',
''code.php'': {
''author_id'': 11543,
''author_name'': ''Jamie Rumbelow'',
''file_hash'': ''a26hb3vpq22''
''access'': ''public''
}
}
Esto nos permite asociar metadatos sobre ese archivo, verificar la autenticidad e integridad, mantener datos persistentes, especificar atributos de archivos y hacer mucho más. Luego podemos mantener información sobre revisiones específicas en el archivo 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
},
]
}
Este es un plan de esquema básico para un sistema de control de versiones de archivos: me gusta esta idea y cómo funciona, y he usado JSON en el pasado para lograr un gran efecto con estructuras de datos ricas como esta. Este tipo de datos simplemente no es adecuado para una base de datos relacional como MySQL: a medida que obtenga más revisiones y más archivos, la base de datos crecerá más y más, de esta manera puede escalonar las revisiones en múltiples archivos, mantener copias de seguridad de todo, hacer Seguro que tienes datos persistentes en las interfaces y plataformas, etc.
Espero que esto te haya dado una idea, ¡y con suerte también proporcionará algo de reflexión para la comunidad!
Creo que esto describe el sistema perfecto para versionar
Echa un vistazo a ProjectPier (originalmente ActiveCollab ). Tiene un sistema similar a esto y se puede ver su fuente.
No es tan simple como parece. Lea este artículo de Eric Sink sobre las implicaciones del almacenamiento para almacenar estos archivos.
Quizás una mejor pregunta sería qué tipo de archivos se están cargando, y se prestan bien a las versiones (como archivos de texto)
Para un esquema de base de datos, es probable que necesite dos conjuntos de información, archivos y versiones de archivo. Cuando se almacena un archivo nuevo, también se crea una versión inicial. La última versión aprobada debería almacenarse explícitamente, mientras que la versión más nueva se puede seleccionar de la tabla de versiones (ya sea encontrando la versión más alta relacionada con el archivo, o la fecha más reciente si almacena cuando se crean)
files(id,name,approved_version)
file_versions(id,fileId)
las versiones de archivos podrían almacenarse utilizando sus ids (por ejemplo, ''/ fileId / versionId'' o ''/ fileId / versionId_fileName'') en el servidor, con su nombre original almacenado en la base de datos.
Por el amor de Dios, no lo hagas . Realmente no quieres ir por este camino.
Deténgase y piense en la imagen más grande por un momento. Desea conservar versiones anteriores de documentos, lo que significa que, en algún momento, alguien querrá ver algunas de esas versiones anteriores, ¿verdad? Y luego van a preguntar: "¿Cuál es la diferencia entre la versión 3 y la versión 7"? Y luego van a decir: "Quiero volver a la versión 3, pero mantener algunos de los cambios que puse en la versión 5, mmm, ¿de acuerdo?"
El control de versiones no es trivial, y no hay necesidad de reinventar la rueda. Hay muchos sistemas de control de versiones viables, algunos incluso gratuitos.
A largo plazo, será mucho más fácil aprender la API de uno de estos sistemas y codificar un front-end web que ofrezca a los usuarios el subconjunto de características que están buscando (ahora).
No codificaría un editor de texto para sus usuarios, ¿verdad?
Puede obtener inspiración de there .
En cuanto a tu comentario:
En cuanto a la estructura de una base de datos, puedes probar este tipo de estructura (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`)
);
Documents es un contenedor lógico, y Revisions contiene enlaces reales a los archivos. Cada vez que una persona actualice un nuevo archivo, cree una entrada en cada una de estas tablas, la de Revisiones que contiene un enlace al insertado en Documentos.
La tabla M2M_UserRev permite asociar varios usuarios a cada revisión de un documento.
Cuando actualice un documento, inserte solo en Revisiones, con alink en el Documento correspondiente. Para saber a qué documento vincular, puede usar convenciones de nomenclatura o pedirle al usuario que seleccione el documento correcto.
Para la arquitectura del sistema de archivos de tus archivos, realmente no importa. Simplemente cambiaría el nombre de mis archivos a algo único antes de que se almacenaran en el servidor, y mantendría el nombre del archivo de usuario en la base de datos. Simplemente almacene los archivos renombrados en una carpeta en cualquier lugar y conserve la ruta en la base de datos. De esta manera, sabes cómo cambiarle el nombre cuando el usuario lo solicita. También puede conservar el nombre original dado por el usuario si está seguro de que será único, pero no me fiaría demasiado de él. Es posible que pronto vea dos revisiones diferentes con el mismo nombre y una sobreescribiendo la otra en su sistema de archivos.
Recientemente construí un sistema de control de versiones simple para algunas entidades de datos estáticos. El requisito era tener una versión ''Activa'' y 0 o 1 versiones ''pendientes''.
Al final, mi entidad versionada tenía los siguientes atributos relevantes para el control de versiones.
VersionNumber (int / long) ActiveVersionFlag (booleano)
Dónde:-
- solo 1 entidad puede ser ActiveVersionFlag = ''Y''
- solo 1 entidad puede ser Número de versión> la versión ''Activa'' (es decir, la versión ''pendiente'')
El tipo de operaciones que permití fueron
Clona la versión actual.
- Fallar si ya hay una versión> el Número de Versión de la versión ''Activa''
- Copie todos los datos a la nueva versión
- incrementar el número de versión en uno
Activar la versión pendiente
- Fallar si la versión especificada no es la versión ''Activa'' + 1
- encuentre la versión ''Activa'' y configure su ActiveVersionFlag en ''N''
- establecer ActiveVersionFlag de la versión ''pendiente'' en ''Y''
Eliminar la versión pendiente
- Eliminar la entidad pendiente
Esto fue razonablemente exitoso y mis usuarios ahora se clonan y se activan todo el tiempo :)
Miguel
Subir archivos es 1990-ty =) ¡Mira Google Wave! Puedes simplemente construir tu aplicación completa alrededor de su marco de ''control de versiones''.
Esquema de la base de datos
Para mantenerlo extremadamente simple, elegiría el siguiente diseño de base de datos. Estoy separando el concepto de " archivo " (igual que un archivo de sistema de archivos) del concepto de " documento " (el grupo gerarquico de documentos).
Entidad usuaria :
- identidad de usuario
- nombre de usuario
Entidad del grupo :
- Identificación del grupo
- Nombre del grupo
Entidad de archivo :
- fileId (una secuencia)
- fileName (el nombre que el usuario le da al archivo)
- sistema de archivosFullPath
- uploadTime
- uploaderId (id del usuario uploader)
- ownerGroupId
Entidad del documento :
- documentId
- parentDocumentId
- ID de archivo
- número de versión
- tiempo de creación
- esta aprobado
Cada vez que se carga un archivo nuevo, se crea un registro "Archivo" y también un nuevo "Documento". Si es la primera vez que se carga el archivo, parentDocumentId para ese documento sería NULL. De lo contrario, el nuevo registro del documento apuntaría a la primera versión.
El campo "isApproved" (booleano) manejaría el documento como un borrador o una revisión aprobada.
Obtiene el último borrador de un documento simplemente ordenando descender por número de versión o tiempo de carga.
Sugerencias
De cómo describe el problema, debe analizar mejor esos aspectos, antes de pasar al diseño del esquema de la base de datos:
- ¿Cuál es el papel de la entidad "grupal"?
- ¿cómo se relacionan los grupos / usuarios / archivos?
- ¿Qué sucede si dos usuarios de diferentes grupos intentan cargar el mismo documento?
- ¿Necesitarás carpetas? (Probablemente lo haga; mi solución sigue siendo válida, dando un tipo, "carpeta" o "documento", a la entidad "documento")
Espero que esto ayude.