Как реализовать версионность некоторой сущности в базе данных?

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

Сам вижу следующие варианты:

1) В базе данных есть таблица profile, в которой есть поле status, где можно указать, актуальная анкета, новая или старая. Вот расклад:

id | field | field | status
1    --       --       old
2    --       --       actual
3    --       --       new


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

2) Структура, в которой есть некоторая таблица, содержащая в себе названия поля и значение

profile_history
id | field | value        |        version
1  name  Alex                    1
2   age  21                      1
3  name  Alexander               2
3  name  Alexander Great         3


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

Просьба опытных людей подсказать, какой подход наиболее приемлемый и какие у этих двух подходов еще плюсы и минусы, а то пилю проект и не хочу на будущее заложить в него архитектурную какашку))
  • Вопрос задан
  • 235 просмотров
Пригласить эксперта
Ответы на вопрос 3
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Профиль это некоторая сущность, прямо таки и просится назвать его документом и использовать какую нибудь nosql document database.

Что же до вашего случая, в таблице добавьте versionid и тупо копируйте всю запись увеличивая версию.
Согласен места займет больше, но не слишком переусложните схему
Ответ написан
Комментировать
tsklab
@tsklab
Здесь отвечаю на вопросы.
Пользователь - его профиль с датой изменения. Текущий профиль с максимальной датой.

одобряет новый профиль
Добавьте поле дата одобрения и его максимальное значение.

Дата — естественный способ сортировки.
Ответ написан
@DmitriyTitov
Я не специалист по MySQL, но эта СУБД, как и почти все современные реляционные СУБД, поддерживает тип данных JSON. В случаях вроде вашего я "эмулирую" MongoDB в реляционной СУБД создавая таблицу с полем ID - автоинкремент и полем DATA - JSON. И уже в JSON добавьте поле версия и что угодно.
Этим вы также и решите проблему с новыми полями анкеты.
Можно добавить JSON и к существующей таблице, а можно написать утилиту миграции. Оба пути сравнительно простые.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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