Версионное и индексированное хранилище данных - PullRequest
1 голос
/ 10 ноября 2009

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

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

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

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

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

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

выберите имя от лица p, где p.id = (выберите max (id) от лица, где person_id = p.person_id и отметка времени <=: отметка времени) </p>

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

Ответы [ 2 ]

2 голосов
/ 10 ноября 2009

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

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

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

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

0 голосов
/ 11 ноября 2009

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

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

...