Как сохранить старые данные пользователей в старых заказах

Есть две таблицы с пользователями, и с заказами. Структура таблиц не так важна, обычные данные пользователя 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.

→ Ссылка