9

Tengo un sistema CMS que almacena los datos en tablas de la siguiente manera:Manteniendo el historial de cambios de página. Un poco lo hace igual que para las revisiones

Entries Table 
+----+-------+------+--------+--------+ 
| id | title | text | index1 | index2 | 
+----+-------+------+--------+--------+ 

Entries META Table 
+----+----------+-------+-------+ 
| id | entry_id | value | param | 
+----+----------+-------+-------+ 

Files Table 
+----+----------+----------+ 
| id | entry_id | filename | 
+----+----------+----------+ 

Entries-to-Tags Table 
+----+----------+--------+ 
| id | entry_id | tag_id | 
+----+----------+--------+ 

Tags Table 
+----+-----+ 
| id | tag | 
+----+-----+ 

Estoy tratando de implementar un sistema de revisión, un poco como lo ha hecho. Si lo estuviera haciendo por el Entries Table, estaba planeando guardar una copia de todos los cambios en esa tabla en una tabla separada. Como tengo que hacerlo para al menos 4 tablas (la tabla TAGS no necesita tener revisiones) esto no parece en absoluto una solución elegante.

¿Cómo lo harían ustedes?

Por favor, observe que el Tablas Meta se modelan en EAV (entity-attribute-value).

Gracias de antemano.

Respuesta

8

Hola, actualmente estoy trabajando en la solución a un problema similar, lo estoy resolviendo dividiendo mis tablas en dos, una tabla de control y una tabla de datos. La tabla de control contendrá una clave primaria y una referencia en la tabla de datos, la tabla de datos contendrá la clave de revisión de incremento automático y la clave primaria de la tabla de control como una clave externa.

tomar su tabla de entradas como ejemplo

Entries Table 
+----+-------+------+--------+--------+ 
| id | title | text | index1 | index2 | 
+----+-------+------+--------+--------+ 

convierte

entries    entries_data 
+----+----------+ +----------+----+--------+------+--------+--------+ 
| id | revision | | revision | id | title | text | index1 | index2 | 
+----+----------+ +----------+----+--------+------+--------+--------+ 

para consultar

select * from entries join entries_data on entries.revision = entries_data.revision; 

en lugar de actualizar la tabla entries_data utiliza una instrucción de inserción y luego actualizar el la revisión de la tabla de entradas con la nueva revisión de la tabla de entradas.

La ventaja de este sistema es que puede pasar a diferentes revisiones simplemente cambiando la propiedad de revisión dentro de la tabla de entradas. La desventaja es que necesita actualizar sus consultas. Actualmente estoy integrando esto en una capa ORM para que los desarrolladores no se preocupen por escribir SQL de todos modos. Otra idea con la que estoy jugando es que haya una tabla de revisión centralizada que utilicen todas las tablas de datos. Esto le permitiría describir el estado de la base de datos con un solo número de revisión, similar a cómo funcionan los números de revisión de subversión.

+0

¿Por qué alguien desestimó la respuesta de ejrowley? Todavía estoy buscando la mejor solución posible y daré crédito donde se debe crédito. Pero esto parece una solución viable, ¿no? – Frankie

+0

aunque su sistema no sea exactamente lo que estoy buscando; Creo que el esquema de mesa 'Media Wiki' en Edward Williams es una respuesta más cercana en términos de rendimiento y disponibilidad; Creo que tu respuesta está en la línea de respuesta de Edwards con mejores esquemas, así que la acepto. ¡Gracias! – Frankie

6

Tener un vistazo a esta pregunta: How to version control a record in a database

Por qué no tienen una history_table separada para cada tabla (según la respuesta aceptada sobre la cuestión vinculada)? Eso simplemente tiene una clave primaria compuesta de PK de las tablas originales y el número de revisión. De todos modos, deberá almacenar los datos en algún lugar.

+0

tu respuesta es muy interesante. Especialmente el esquema de base de datos 'Media Wiki'. Crea una capa adicional 'tabla -> teclas de revisión -> datos de revisiones' manteniendo la' tabla de datos 'lo más pequeña posible, al tiempo que proporciona un historial de revisiones y puede navegar entre las revisiones de ida y vuelta, como lo hace SO. Todavía me pregunto si hay una manera más * elegante * de almacenarlo. – Frankie

1

Para uno de nuestros proyectos en los que se fueron de la siguiente manera:

Entries Table 
+----+-----------+---------+ 
| id | date_from | date_to | 
+----+--------_--+---------+ 

EntryProperties Table 
+----------+-----------+-------+------+--------+--------+ 
| entry_id | date_from | title | text | index1 | index2 | 
+----------+-----------+-------+------+--------+--------+ 

Más o menos complicado, todavía permite hacer un seguimiento de ciclo de vida completo de objeto. Así que para la consulta de entidades activas que íbamos para:

SELECT 
entry_id, title, text, index1, index2 
FROM 
Entities INNER JOIN EntityProperties 
ON Entities.id = EntityProperties.entity_id 
AND Entities.date_to IS NULL 
AND EntityProperties.date_to IS NULL 

La única preocupación era para una situación con la entidad que está siendo removido (así que pusimos una date_to allí) y luego se restablece por admin.Usando el esquema dado, no hay forma de seguir ese tipo de trucos.

El inconveniente general de cualquier intento como ese es obvio: tienes que escribir toneladas de TSQL donde los DB no versionados irán por algo como selecciona A join B.

Cuestiones relacionadas