Nodge
@Nodge

Организация системы ревизий в базе данных?

Дано:

  1. Приложение, написанное на PHP с MySQL (Yii Framework);
  2. Несколько типов контента, например setting и node. Хранится в разных таблицах со своим набором полей;
  3. Около 10к пользователей приложения с очень частым обновлением одного из типов контента, допустим node. Во время редактирования node может обновляться до нескольких раз в секунду (с созданием новых ревизий). В тоже время, некоторые node могут не обновляться месяцами, а некоторые каждый день по нескольку раз.


Необходимо сделать что-то вроде системы контроля версий, чтобы синхронизировать несколько клиентских приложений с сервером. Хороший пример: расширение для браузеров Xmarks.

Вопрос заключается в том, как хранить ревизии (и изменения в них) в базе MySQL?



Мне на ум пришло такое решение:



Одна таблица, которая хранит все изменения контента. Выглядит это примерно так:


rev action type id args
1 insert node 1421 { text: 'custom node', created: 1236124121 }
2 update node 1421 { text: 'asd', modified: 1237123134 }
3 update node 1421 { title: 'example node', modified: 1238123814 }
3 insert node 1422 { field: new_value }
3 update setting 12 { email: 'Oo@mail.ru' }
4 update node 1422 { field: new_new_value }
4 update setting 12 { email: 'mail@mail.ru' }
5 delete node 1421 {}


  • Rev – номер ревизии пользователя. В рамках одной ревизии может быть несколько записей.
  • Action – тип изменений. insert|update|delete.
  • Type – тип контента. Например, node или setting.
  • Id – идентификатор контента.
  • Args – объект json с логом изменений.


Не знаю, насколько правильно хранить ревизии таким образом, в одной таблице. Допустим, у каждого юзера будет по 5к ревизий – это уже 50 млн. записей! Как с этим будет справляться MySQL, если учесть, что идет постоянная запись в таблицу?



Как можно решить данную проблему наиболее рационально? Готов рассмотреть варианты с использованием других БД, в т.ч. NoSQL.



Большое спасибо за помощь.



UPD:

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

Тогда таблица сократиться в 10 раз, и в ней будет около 5 млн. записей. Насколько это упрощает задачу? Как поведет себя MySQL в таком случае?
  • Вопрос задан
  • 3822 просмотра
Пригласить эксперта
Ответы на вопрос 1
AntonMinsk
@AntonMinsk
Если есть возможность отказа от восстановления старых ревизий, то можно хранить скажем последних N-штук. Если так пугает число записей в БД, то почему не сделать в Вашей таблице другой тип связи, у Вас сейчас один ко многим, а сделать один к одному (по id), а всю историю изменений писать в args, с указанием action, уже непосредственно в args. Тут правда надо помнить о том, что длина полей тоже не бесконечна, и все вероятно не влезет.

Второй вариант — действительно, использовать NoSQL БД, например CouchDb ну или что-нибудь подобное, я думаю, что это будет даже самый правильный вариант.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы