Как сохранить старые данные пользователей в старых заказах
Есть две таблицы с пользователями, и с заказами. Структура таблиц не так важна, обычные данные пользователя ID, ФИО и т.д. и обычные данные по заказам с ценой товаром и привязкой к пользователю кто заказал по ID. Какой подход применить, чтобы в случае изменения какого либо пользователя, в уже созданных заказах оставались те данные пользователя, которые были на момент создания заказа?
Есть пока две идеи. Первая идея, это создать копию таблицы с пользователями, и при создании заказа копировать пользователя в эту таблицу, и заказ привязывать к нему. И при изменении пользователя в основной таблице, в копии останутся его старые данные.
И вторая идея, использовать одну таблицу с пользователями, но при изменении всегда создавать новую запись для этого же пользователя, а старую запись или записи помечать как скрытые.
Или может есть решения получше?
Ответы (1 шт):
Вариант №1 (как делалось на бумаге)
При оформлении заказа в таблицы заказа добавлять не только ID, но и копировать текстовую информацию, которая должна остаться неизменной.
Вариант №2 (подсмотрено у ФИАС)
У записей, к которым может потребоваться доступ не только к текущему значению, но и к старому, фиксированному на определенный момент времени, делается два ID: один неизменный, который остается общим для всех исторических вариантов, второй - уникальный.
Например, это может выглядеть так:
GID; CID; Status; Value
123; 456; - ; Иванов Иван
123; 567; + ; Иванов Иван Иванович
234; 345; - ; Петров Петр
234; 395; - ; Петров Петр Петрович
234; 678; + ; Петров Пётр Петрович
GID (Global ID) - общий неизменный идентификатор, который соответствует некоторой сущности реального мира, в данном случае клиенту. Может быть FK на учетную запись клиента в системе или просто GUID.
CID (Current ID) - идентификатор текущего значения. Уникален в пределах таблицы. Именно он указывается в заказе. Или можно указать оба, но CID точно должен быть.
Status - Показывает состояние записи: актуальное/последнее значение или устаревшее/архивное. В зависимости от выбранной СУБД для ускорения выборки текущего значения по этому полю можно сделать кластеризацию, секционирование или ручное секционирование (текущие и архивные значения держать в двух разных таблицах, и сам столбец тогда не нужен).
Также можно дополнить другими полями для определения хронологии, например: порядковый номер, даты начала и конца действия, ссылки на предыдущее и следующее значения.
При «редактировании» записи, редактируемая запись помечается как более не актуальная, а новое значение записывается новой строкой с новым CID.