Вопрос

У меня есть требование хранить все версии объекта в легко индексируемом виде, и мне было интересно, есть ли у кого-нибудь данные о том, какую систему использовать.

Без управления версиями система представляет собой просто реляционную базу данных со строкой для каждого, например, человека.Если состояние пользователя изменяется, эта строка изменяется, чтобы отразить это.При управлении версиями запись должна быть обновлена таким образом, чтобы мы всегда могли вернуться к предыдущей версии.Если бы я мог использовать временную базу данных, это было бы бесплатно, и я мог бы спросить: "каково состояние всех людей по состоянию на вчерашний день в 14:00, проживающих в Дублине, в возрасте 30 лет".К сожалению, похоже, что нет ни одного зрелого проекта с открытым исходным кодом, который мог бы выполнять временные функции.

Действительно неприятный способ сделать это - просто вставлять новую строку при изменении состояния.Это приводит к дублированию, так как у пользователя может быть много полей, но за одно обновление изменяется только одно.Кроме того, в этом случае довольно медленно выбирается правильная версия для каждого пользователя, которому задана временная метка.

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

Поэтому мне было интересно, сталкивался ли кто-нибудь с чем-то подобным раньше и как они подходили к этому?

Обновить Как предложил Аарон, вот запрос, который мы используем в настоящее время (в mysql).Это определенно медленно для нашей таблицы с > 200 тыс. строк.(id = ключ таблицы, person_id = идентификатор для каждого пользователя, дублируется, если у пользователя много ревизий)

выберите имя из person p, где p.id = (выберите max (id) из person, где person_id = p.person_id и временная метка <= :временная метка)

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

Это было полезно?

Решение

Есть два способа решить эту проблему.Оба предполагают, что вы всегда вставляете новые строки.В каждом случае вы должны вставить временную метку (created), который сообщает вам, когда строка была "изменена".

Первый подход использует число, чтобы подсчитать, сколько экземпляров у вас уже есть.Первичный ключ - это ключ объекта плюс номер версии.Проблема с таким подходом, по-видимому, заключается в том, что вам понадобится select max(version) чтобы внести изменения.На практике это редко является проблемой, поскольку для всех обновлений из приложения вы должны сначала загрузить текущую версию person, изменить ее (и увеличить версию), а затем вставить новую строку.Итак, реальная проблема заключается в том, что такая конструкция затрудняет запуск обновлений в базе данных (например, присвоение свойства многим пользователям).

Следующий подход использует ссылки в базе данных.Вместо составного ключа вы присваиваете каждому объекту новый ключ, и у вас есть replacedBy поле, содержащее ключ следующей версии.Такой подход упрощает поиск текущей версии (... where replacedBy is NULL).Однако обновления - это проблема, поскольку вы должны вставить новую строку и обновить существующую.

Чтобы решить эту проблему, вы можете добавить обратный указатель (previousVersion).Таким образом, вы можете вставить новые строки, а затем использовать обратный указатель для обновления предыдущей версии.

Другие советы

Вот (несколько устаревший) обзор литературы по временным базам данных: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf

Я бы порекомендовал потратить время на то, чтобы посидеть с этими ссылками и / или Google Scholar - Ученый попытаться найти несколько хороших методов, которые соответствуют вашей модели данных.Удачи вам!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top