Введение: На днях я подумал о новой структуре базы данных для нового приложения и понял, что нам нужен способ эффективного хранения исторических данных. Я хотел, чтобы кто-то еще посмотрел, есть ли проблемы с этой структурой. Я понимаю, что этот метод хранения данных может быть очень хорошо изобретен ранее (я почти уверен, что он есть), но я понятия не имею, есть ли у него имя и некоторые поисковые запросы Google, которые я попробовал, ничего не дали.
Проблема: Допустим, у вас есть таблица для заказов, а заказы связаны с таблицей клиента для клиента, разместившего заказ. В обычной структуре базы данных вы можете ожидать чего-то вроде этого:
orders
------
orderID
customerID
customers
---------
customerID
address
address2
city
state
zip
Довольно просто, orderID имеет внешний ключ customerID, который является первичным ключом таблицы клиентов. Но если мы должны пойти и запустить отчет по таблице заказов, мы собираемся присоединиться к таблице клиентов в таблице заказов, которая вернет текущую запись для этого идентификатора клиента. Что, если при размещении заказа адрес клиентов был другим, и впоследствии он был изменен. Теперь наш заказ больше не отражает историю адреса клиентов, на момент размещения заказа. В основном, изменив запись клиента, мы просто изменили всю историю для этого клиента.
Теперь есть несколько способов обойти это, одним из которых было бы скопировать запись при создании заказа. То, что я придумал, - это то, что, по моему мнению, будет более простым способом сделать это, возможно, немного более элегантным, и имеет дополнительный бонус регистрации в любое время, когда будет сделано изменение.
Что делать, если бы я сделал такую структуру:
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.
Может ли кто-нибудь увидеть какие-либо проблемы с этим подходом, будь то с точки зрения дизайна или соображения производительности, почему это плохо. Помните, что независимо от того, что я делаю, мне нужно убедиться, что исторические данные сохранены, чтобы последующие обновления записей не меняли историю. Есть ли способ лучше? Это известная идея, которая имеет имя или любую документацию на нем?
Спасибо за любую помощь.
Update: Это очень простой пример того, что я действительно буду иметь. Мое реальное приложение будет иметь "заказы" с несколькими внешними ключами для других таблиц. Информация о местонахождении/местоположении, информация о клиенте, информация об объекте, информация о пользователе и т.д. Несколько раз мне предлагалось скопировать информацию в запись заказа, и я видел, как это делалось много раз, но это приведет к записи с сотнями столбцов, что в этом случае действительно невозможно.