Просьба поделиться опытом/накидать ссылок на реализацию версионности состояния сущностей. То есть при каждом новом апдейте сущности надо сохранять его предыдущее состояние, при этом в дальнейшем должна быть возможность просмотреть все предыдущие состояния и работать с произвольной выбранной версией. Используется mssql + nhibernate.
Здравствуйте, Аноним, Вы писали:
А>Просьба поделиться опытом/накидать ссылок на реализацию версионности состояния сущностей. То есть при каждом новом апдейте сущности надо сохранять его предыдущее состояние, при этом в дальнейшем должна быть возможность просмотреть все предыдущие состояния и работать с произвольной выбранной версией. Используется mssql + nhibernate.
Занимает мало места, зато сложен в реализации, нетривиален в восстановлении предыдущей версии и требует размышлений над типом полей old_value и new_value.
M>Занимает много места, зато прост в реализации, быстр и удобен.
Прост, пока не появятся несколько версионных сущностей и отношения между ними. Вот тогда начинается самое интересное
M>2. Хранить изменения
Возможна комбинация двух подходов. Хранить актуальную версию сущности в одной таблице, и историю изменений в другой таблице идентичной структуры за исключением первичного ключа.
Здравствуйте, Аноним, Вы писали:
А>Просьба поделиться опытом/накидать ссылок на реализацию версионности состояния сущностей. То есть при каждом новом апдейте сущности надо сохранять его предыдущее состояние, при этом в дальнейшем должна быть возможность просмотреть все предыдущие состояния и работать с произвольной выбранной версией. Используется mssql + nhibernate.
Я реализовал такую версионность. У меня в таблице версий хранится базовое состояние объекта и изменения. Также есть таблицы с текушим состоянием.
Минусы: большие объемы кода, т.к. надо делать по отдельному классу, в котором происходит diff и merge, на каждую сущность; скорость работы не является сильной стороной.
Плюсы: "честная" версионность, можно сравнивать изменения между любыми версиями.
Здравствуйте, wildwind, Вы писали: W>Для конструктивного обсуждения расскажи о своих сущностях и о предметной области.
1. Очень бы хотелось весь механизм реализовать на уровне ORM а не на хранимках/триггерах и прочей пакости.
2. Очень бы хотелось, что бы механизм версионности в 95% случаев был невидим для юзера, т.е. о наличии версий вспоминаем когда этого хотим (воспользовтаься конкретной версией объекта).
3. Предметная область не имеет значения, случай достаточно общий и привязаться к какой-нибудь особенности врятли реально. Модельная ситуация — есть сущность Way (путь) и точки пути (Vertexes). В БД путь отображается на таблицу ways, а точки пути — таблицу vertexes c foreign key на ways. Есть возможность как добавить или изменить vertexes так и ways, при этом впоследствии надо иметь возможность получить состояние объекта Way перед каждым его изменением.
На практике имеет десятки таблиц. Пока вижу три варианта:
1. Воспользоваться идеей отсюда, таким образом имеем обычные тьаблицы с последним снапшотом и их теневые копии с дополнительными полями для версионности. И героически пытаемся сдружить это с хиберенетом посредством интерсепоторов и т.д.
2. Снапшот реализуем через view, т.е. обычных таблиц не существует и строятся представления на основе таблиц с историей.
3. Непонятно как пытаемся обойтись только таблицами с историей без представлений. Не отображаем аерсионные служебнее поля на доменные объекты и пытаемся как то это сдружить с хибернетом .
ЗЫ. Все три варианта очень геморны со связанными таблицами...
Здравствуйте, Aviator, Вы писали:
A>1. Очень бы хотелось
Да я не о том спрашивал..
A>3. Предметная область не имеет значения,
Имеет, еще как имеет. о-настоящему эффективные решения всегда специфические.
Объемы данных и паттерны доступа — вот что основное IMHO, и что я хочу вывести из предметной области.
К примеру, если 99% обращений идет к текущим версиям, а 1% к предыдущим и время отклика в этом случае не критично — это один расклад.
Если 80% на 20% и работать должно так же быстро — это уже другой.
Если же вообще объектов мало (~1e6) и гдавное скорость разработки и сопровождаемость — это третий.
Здравствуйте, wildwind, Вы писали:
W>Здравствуйте, Aviator, Вы писали:
A>>1. Очень бы хотелось W>Да я не о том спрашивал..
A>>3. Предметная область не имеет значения, W>Имеет, еще как имеет. о-настоящему эффективные решения всегда специфические. W>Объемы данных и паттерны доступа — вот что основное IMHO, и что я хочу вывести из предметной области.
W>К примеру, если 99% обращений идет к текущим версиям, а 1% к предыдущим и время отклика в этом случае не критично — это один расклад. W>Если 80% на 20% и работать должно так же быстро — это уже другой. W>Если же вообще объектов мало (~1e6) и гдавное скорость разработки и сопровождаемость — это третий.
В 80% случаев обращение идёт к объектам последней версии, версионность используется в основном для отчётов и ряда специфичных задач. Объектов будет достаточно много, допускается, что обращение к предыдущем версиям будет более медленным. Допускается, что тратится некоторое время на переключение на предыдущую версию объекта. Сопровождаемость естественно важна, время разработки не так критично, лишь бы это было оправдано результатом.
Здравствуйте, Aviator, Вы писали:
A>1. Очень бы хотелось весь механизм реализовать на уровне ORM а не на хранимках/триггерах и прочей пакости.
Плохая идея..
A> И героически пытаемся сдружить это с хиберенетом посредством интерсепоторов и т.д.
Целостность этого решения тоже будет гибернейт на интерцепторах обеспечивать?
Здравствуйте, IB, Вы писали: IB>Целостность этого решения тоже будет гибернейт на интерцепторах обеспечивать?
Если есть хорошее решение на основе хранимок, которое не мешает работе маппера я не против...
Здравствуйте, Aviator, Вы писали:
A>Если есть хорошее решение на основе хранимок, которое не мешает работе маппера я не против...
Мапперу вообще пофиг что на что мапить, если маперу мешает работа хранимок и триггеров — выкидывай такой мапер.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, Aviator, Вы писали:
A>>Если есть хорошее решение на основе хранимок, которое не мешает работе маппера я не против... IB>Мапперу вообще пофиг что на что мапить, если маперу мешает работа хранимок и триггеров — выкидывай такой мапер.
Конечно, надо писать свой, как делают настоящие пацаны.
PS Кроме громогласных лозунгов конструктивные предложения будут?
Здравствуйте, Aviator, Вы писали:
A>Конечно, надо писать свой, как делают настоящие пацаны.
Я не знаю что делают настоящие пацаны, зато я знаю, что ORM-у должно быть пофигу что происходит в базе.
А уж настоящий ты пацан или нет — это пожалуйста сам решай.
A>конструктивные предложения будут?
Убрать всю механику версионирования в базу — вполне себе конструктивное предложение.
В общем случае — решение не тривильно, как видно по постам ниже и выше.
Я бы начал с :
1. Нарисовал бы модель данных, где требуется версионность.
2. На основе анализа 1 выявил бы : количество сущностей для версионности. Сложность взаимосвязей между ними. нужны ли будут взаимосвязи.
И выбрал бы один из двух, уже предложенных подходов (либо гибрид)
В принципе можно еще пожевать идею насчет вот такой вот структуры данных (для простоты — 1 форма)
"ИД" "название атрибута" "Объект к которому относится" "Версия" "значение"
Здравствуйте, malkolinge, Вы писали:
M>В общем случае — решение не тривильно, как видно по постам ниже и выше.
Тривиального решения и не ожидается.
M>Я бы начал с :
M>1. Нарисовал бы модель данных, где требуется версионность.
Везде
M>2. На основе анализа 1 выявил бы : количество сущностей для версионности. Сложность взаимосвязей между ними. нужны ли будут взаимосвязи.
Достаточно сущностей, штук 30 как миниум. В основном отношения один ко многим.
Пока склоняюсь к генерации теневой таблице на каждую таблицу и триггеров, которые по апдейтам/дилитам будут копировать данные в теневые таблицы. В теневые таблицы копируют исходные с добавлением полей даты изменения и номера версии записи, первичным ключём в теневой таблице является составной id+version. Так как чтений базы в разы больше правок, есть надежда что это будет работать.
30 сущностей это конечно беда.
тогда такой вопрос все ли атрибуты в них требуют версионности ?
Сильно ли сущности отличаются друг от друга ? Нельзя ли посторить иерархию так, чтобы она оказалась макимаьно простой ? Нельзя ли замапить все эти сущности на как можно меньшее количество таблиц /(про стратегии реализации наследования в Хибернейте, я надеюсь Вы помните)