Предисловие. На днях я думал о новой структуре базы данных для нового приложения и понял, что нам нужен способ эффективного хранения исторических данных.Я хотел, чтобы кто-то еще посмотрел и посмотрел, есть ли проблемы с этой структурой.Я понимаю, что этот метод хранения данных вполне мог быть изобретен ранее (я почти уверен, что он есть), но я не знаю, есть ли у него имя, и некоторые поиски в Google, которые я пробовал, ничего не дали.
Проблема: допустим, у вас есть таблица заказов, а заказы связаны с таблицей клиентов для клиента, разместившего заказ.В обычной структуре базы данных вы можете ожидать что-то вроде этого:
orders
------
orderID
customerID
customers
---------
customerID
address
address2
city
state
zip
Довольно просто, orderID имеет внешний ключ customerID, который является первичным ключом таблицы customer.Но если мы собираемся запустить отчет по таблице заказов, мы собираемся присоединить таблицу клиентов к таблице заказов, которая вернет текущую запись для этого идентификатора клиента.Что если при размещении заказа адрес клиента был другим, и он впоследствии был изменен.Теперь наш заказ больше не отражает историю адресов этих клиентов на момент размещения заказа.По сути, изменяя запись о клиенте, мы просто изменили всю историю для этого клиента.
Теперь есть несколько способов обойти это, одним из которых будет копирование записи при создании заказа.Однако я пришел к выводу, что, как мне кажется, это будет более простой способ сделать это, возможно, немного более элегантным и с дополнительным бонусом регистрации в любое время, когда будут внесены изменения.
Что, если я это сделалструктура, подобная этой:
orders
------
orderID
customerID
customerHistoryID
customers
---------
customerID
customerHistoryID
customerHistory
--------
customerHistoryID
customerID
address
address2
city
state
zip
updatedBy
updatedOn
, пожалуйста, простите за форматирование, но я думаю, что вы можете увидеть идею.По сути, идея заключается в том, что каждый раз, когда клиент изменяется, вставляется или обновляется, идентификатор customerHistoryID увеличивается, а таблица клиентов обновляется с использованием новейшего идентификатора customerHistoryID.Таблица заказов теперь указывает не только на идентификатор клиента (который позволяет просматривать все ревизии в записи клиента), но также на идентификатор клиента, который указывает на конкретную ревизию записи.Теперь заказ отражает состояние данных на момент его создания.
Добавив столбец updatedby и updatedon в таблицу customerHistory, вы также можете увидеть «журнал аудита» данных, чтобы вы моглипосмотрим кто внес изменения и когда.
Один потенциальный недостаток может быть удаление, но я не очень беспокоюсь об этом для этой необходимости, так как ничего не должно быть удалено.Но даже в этом случае тот же эффект может быть достигнут при использовании activeFlag или чего-то подобного в зависимости от области данных.
Я думаю, что все таблицы будут использовать эту структуру.Каждый раз, когда извлекаются исторические данные, они объединяются с таблицей истории, используя customerHistoryID, чтобы показать состояние данных для этого конкретного заказа.
Получить список клиентов легко, достаточно просто присоединиться к таблице клиентов по customerHistoryID.
Может кто-нибудь увидеть какие-либо проблемы с этим подходом, как с точки зрения дизайна, так и с точки зрения производительностипричины, почему это плохо.Помните, что независимо от того, что я делаю, мне нужно убедиться, что исторические данные сохраняются, чтобы последующие обновления записей не меняли историю.Есть ли способ лучше?Это известная идея, у которой есть имя, или какая-либо документация по ней?
Спасибо за любую помощь.
Обновление: Это очень простой пример того, что я действительно собираюсь получить.В моем реальном приложении будут «заказы» с несколькими внешними ключами для других таблиц.Информация о месте отправления / назначения, информация о клиенте, информация об объекте, информация о пользователе и т. Д. Несколько раз мне предлагалось скопировать информацию в запись заказа в тот момент, и я видел, как это делалось много раз,но это приведет к записи с сотнями столбцов, что на самом деле невозможно в этом случае.