В статье показан пример, раскрывающий некоторые тонкости, полезные при проектировании справочников.АмбулаПредставим, что у вас есть MVP и вы сделали справочник сотрудников для бухгалтера, самым тривиальным образом, и запустили в эксплуатацию.Явление бухгалтера первое. К вам приходит бухгалтер и говорит, что сотрудница Иванова поменяла фамилию на Петрова. Вы заходите в справочник и меняете фамилию сотрудницы.Явление бухгалтера второе. Приходит бухгалтер и говорит, что в отчете за прошлый квартал Петрова отображается неправильно, поскольку тогда она была еще Иванова.Осознание. Очевидно, что исправить этот дефект можно с помощью учетного версионирования строк с указанием даты ввода в учет нового значения. Ок, дорабатываем.Явление бухгалтера третье. Еще через 3 месяца бухгалтер приходит опять и говорит, что у этой же сотрудницы ошибка в отчестве. Вы заходите в справочник, исправляете ошибку, и в результате порождается новая версия записи с правильным отчеством.Явление бухгалтера четвертое. Бухгалтер звонит и жалуется, что в отчетах за предыдущие кварталы отчество сотрудницы выводится неправильно.Просветление. Тут приходит понимание, что в справочнике нужно сделать кнопку "Сохранить" немного сложнее. При нажатии кнопки необходимо спросить у пользователя, что, собственно, он хочет сделать, исправить ошибку или актуализировать значение?Исправить ошибкуВ этом случае версия записи порождаться не будет, но исправление должно быть сделано в актуальной и исторических версиях.Актуализировать значениеВ этом случае нужно потребовать дату ввода в учет нового значения. Будет порождена новая версия записи.Прочие подсказкиВ реальности кейсы могут быть еще более запутанные, поэтому также необходим UI для управления историческими версиями.Следует понимать, что учетное версионирование не заменяет механизм логирования действий пользователей.Версионность можно организовать, добавив в таблицу насколько технических полей:idИдентификатор строки. Обязательное.actual_idИдентификатор последней (актуальной) версии. Обязательное. Для актуальной версии id = actual_id.actual_fromДата старта срока актуальности. Обязательное. Значение для первой версии = 2001.01.01.actual_toДата, до которой версия была актуальна. Обязательное. Значение для последней (актуальной) версии = 3001.01.01Кортежи actual_id + actual_from должны быть уникальными.Если в отчетах нужно вывести актуальные значения, то JOIN делается к id, если нужно вывести исторические значения, то JOIN делается к actual_id с добавлением условия на срок актуальности. Примерно так …fact JOIN staff ON fact.staff_id = staff.actual_id and fact.datetime >= staff.actual_from and fact.datetime < staff.actual_to