Diseño de base de datos temporal, con un giro (filas en vivo frente a borradores)

Estoy buscando implementar versiones de objetos con el toque adicional de tener que tener objetos en vivo y en borrador, y podría usar los conocimientos de alguien con experiencia en esto, ya que estoy empezando a preguntarme si es posible sin trucos potencialmente horribles .

Lo dividiré en publicaciones con etiquetas por el bien del ejemplo, pero mi caso de uso es un poco más general (involucra dimensiones que cambian lentamente -http: //en.wikipedia.org/wiki/Slowly_changing_dimensio).

Suponga que tiene una tabla de publicaciones, una tabla de etiquetas y una tabla post2tag:

posts (
 id
)

tags (
 id
)

post2tag (
 post_id fkey posts(id),
 tag_id fkey tags(id)
)

Necesito un par de cosas:

Puede mostrar exactamente cómo se veía una publicación en una fecha y hora arbitraria, incluso para las filas eliminadas. Mantenga un registro de quién está editando qué, para un seguimiento de auditoría completo.Necesita un conjunto de vistas materializadas (tablas "en vivo") en aras de mantener la integridad referencial (es decir, el registro debe ser transparente para los desarrolladores). Necesita ser apropiadamente rápido para vivir las últimas filas de borrador.Puede tener un borrador de publicación coexistiendo con una publicación en vivo.

He estado investigando varias opciones. Hasta ahora, lo mejor que he encontrado (sin los puntos # 4 / # 5) se parece un poco a la configuración híbrida SCD type6, pero en lugar de tener un booleano actual, hay una vista materializada para la fila actual. Para todos los efectos, se ve así:

posts (
 id pkey,
 public,
 created_at,
 updated_at,
 updated_by
)

post_revs (
 id,
 rev pkey,
 public,
 created_at,
 created_by,
 deleted_at
)

tags (
 id pkey,
 public,
 created_at,
 updated_at,
 updated_by
)


tag_revs (
 id,
 public,
 rev pkey,
 created_at,
 created_by,
 deleted_at
)

post2tag (
 post_id fkey posts(id),
 tag_id fkey tags(id),
 public,
 created_at,
 updated_at,
 updated_by
)

post2tag_revs (
 post_id,
 tag_id,
 post_rev fkey post_revs(rev), -- the rev when the relation started
 tag_rev fkey tag_revs(rev), -- the rev when the relation started
 public,
 created_at,
 created_by,
 deleted_at,
 pkey (post_rev, tag_rev)
)

Estoy usando pg_temporal para mantener índices en el período (created_at, deleted_at). Y mantengo las diversas tablas sincronizadas usando disparadores. Yada yada yada ... Creé los desencadenantes que permiten cancelar una edición de publicaciones / etiquetas de tal manera que el borrador se almacena en las revoluciones sin ser publicado. Funciona muy bien.

Except cuando necesito preocuparme por las relaciones relacionadas con el borrador de la fila en post2tag. En ese caso, todo el infierno se desata, y esto me insinúa que tengo algún tipo de problema de diseño allí. Pero me estoy quedando sin ideas ...

He considerado introducir la duplicación de datos (es decir, se introducen n filas post2tag para cada borrador de revisión). Este tipo de trabajo funciona, pero tiende a ser mucho más lento de lo que me gustaría que fuera.

He considerado introducir tablas de borradores para el "último borrador", pero esto rápidamente tiende a volverse muy feo.

He considerado todo tipo de banderas ...

Así que pregunta: ¿hay un medio generalmente aceptado de administrar filas en vivo versus no en vivo en un entorno controlado de versión de fila? Y si no, ¿con qué has intentado y has tenido un éxito razonable?

Respuestas a la pregunta(5)

Su respuesta a la pregunta