Мне требуется хранилище данных, которое будет поддерживать не только историю изменений, внесенных в данные (это легко сделать), но также хранить любое количество предлагаемых изменений в данных, включая цепочку предложений (т. е. предложение по предложению).
Думайте об этих «изменениях» как о действительно длительных транзакциях, которые сохраняются в базе данных и имеют продолжительность жизни от минут до лет.
Они создаются (предлагаются), а затем либо откатываются (фактически удаляются), либо фиксируются, после фиксации они становятся действующими данными, видимыми третьим сторонам.
Конечно, все это требует некоторой формы разрешения конфликтов, поскольку предлагаемые изменения могут находиться в противоречивых состояниях (например, изменение A предлагает удалить запись, а изменение B предлагает ее обновить — если изменение A будет зафиксировано первым, тогда изменение B придется отменить)
Я не нашел готового продукта, который может это сделать. Ближе всего к этому был Oracle Workspace Manager, но он не предусматривал изменения при изменении или возможности просмотра предлагаемых удалений. Единственный способ добиться этого — иметь набор общих столбцов в моих версионных таблицах:
Идентификатор корня: обязательно — установите один раз то же значение, что и первичный ключ, при создании первой версии записи. Он представляет собой первичный ключ за все время и копируется в каждую версию записи. Вы должны учитывать корневой идентификатор при именовании столбцов отношения (например, PARENT_ROOT_ID вместо PARENT_ID). Поскольку корневой идентификатор также является первичным ключом исходной версии, внешние ключи могут быть созданы против фактического первичного ключа — фактическая желаемая строка будет определяться фильтрами версий, определенными ниже.
Идентификатор изменения: требуется — каждая запись создается, обновляется и удаляется посредством изменения.
Копировано из ID: Nullable — null указывает на вновь созданную запись, not-null указывает, из какого ID записи эта строка была клонирована/разветвлена при обновлении/удалении.
Действительно с даты/времени: Nullable — null указывает на предложенную запись, not-null указывает, когда запись стала текущей. К сожалению, нельзя разместить уникальный индекс для корневого идентификатора/действующего источника, поскольку для любого корневого идентификатора может быть несколько нулевых значений. (Если вы не хотите ограничиться одним предлагаемым изменением для каждой записи)
Действительно по дате/времени: Nullable — null указывает на текущий или предлагаемый, not-null указывает, когда это стало историческим. Технически не требуется, но помогает ускорить поиск текущих данных. Это поле может быть повреждено ручным редактированием, но в этом случае его можно восстановить из даты/времени вступления в силу.
Флаг удаления: логическое значение — устанавливается в значение true, когда предлагается удалить запись после того, как она станет текущей. Когда удаления зафиксированы, их дата/время вступления в силу устанавливается на то же значение, что и дата/время вступления в силу, отфильтровывая их из текущего набора данных.
Запрос для получения текущего состояния данных в определенный момент времени будет выглядеть так:
SELECT * FROM table WHERE EFFECTIVE_FROM <= :Now AND (EFFECTIVE_TO IS NULL OR EFFECTIVE_TO > :Now)
Запрос для получения текущего состояния данных в соответствии с изменением будет выглядеть так:
SELECT * FROM table WHERE (CHANGE_ID IN :ChangeIds OR (EFFECTIVE_FROM <= :Now AND (EFFECTIVE_TO IS NULL OR EFFECTIVE_TO > :Now) AND ROOT_ID NOT IN (SELECT ROOT_ID FROM table WHERE CHANGE_ID IN :ChangeIds)))
Обратите внимание, что этот второй запрос содержит первый запрос на основе времени для наложения текущих данных на предлагаемые измененные данные.
Столбец идентификатора изменения относится к первичному ключу таблицы изменений, которая также содержит столбец родительского идентификатора (обнуляемый), обеспечивающий функциональность изменения при изменении. Следовательно, второй запрос относится к идентификатору измененияs, а не к одному идентификатору изменения. Я фильтрую несколько версий в сценарии изменения при изменении в клиенте и не использую SQL, поэтому он не отображается в этих запросах (клиент имеет связанный список идентификаторов изменений в памяти, и если извлекается более 1 версии строки он использует связанный список, чтобы определить, какую версию использовать).
Кто-нибудь знает готовый продукт, который я мог бы использовать? Это большой объем работы, связанный с этим управлением версиями, и вводит всевозможные проблемы.