Дизайн временной базы данных с изюминкой (живые и черновые строки)

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

Я разобью это на сообщения с тегами ради примера, но мой вариант использования немного более общие (с медленно меняющимися размерами - http: //en.wikipedia.org / wiki / Slowly_changing_dimension ).

Предположим, у вас есть таблица сообщений, таблица тегов и таблица post2tag:

posts (
 id
)

tags (
 id
)

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

Мне нужна пара вещей:

  1. Возможность точно показать, как сообщение выглядело в произвольную дату и время, в том числе для удаленных строк.
  2. Следите за тем, кто что редактирует, для полного контрольного журнала.
  3. Требуется набор материализованных представлений ("живых" таблиц) для ради сохранения ссылочной целостности (т. е. ведение журнала должно быть прозрачным для разработчиков).
  4. Должен быть достаточно быстрым для живых и последних черновых строк.
  5. Возможность сосуществования черновиков постов с живым сообщением.

Я исследовал различные варианты. На данный момент лучшее, что я придумал (без точек №4 / №5), немного похоже на гибридную установку SCD type6, но вместо текущего логического значения существует материализованное представление для текущей строки. Во всех смыслах это выглядит так:

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

Я использую pg_temporal для поддержки индексов на периоде (created_at, deleted_at). И я поддерживаю синхронизацию различных таблиц с помощью триггеров. Yada yada yada ... Я создал триггеры, которые позволяют отменить редактирование постов / тегов таким образом, чтобы черновик сохранялся в ревизиях без публикации. Он отлично работает.

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

Я рассматривал возможность дублирования данных (т.е. n строк post2tag, вводимых для каждой черновой версии). Этот вид работает, но имеет тенденцию быть намного медленнее, чем я бы хотел.

Я подумывал о введении таблиц черновиков для «последнего черновика», но это быстро становится очень-очень некрасивым.

] Я рассмотрел всевозможные флаги ...

Итак, вопрос: есть ли общепринятые средства управления живыми и неактивными строками в среде с контролем версий строк? А если нет, то что вы пробовали и с чем были достаточно успешны?

17
задан jangorecki 23 May 2015 в 22:00
поделиться