Дублирование данных в базе данных по сравнению с дизайном приложения

У меня есть вопрос о дизайне приложения, касающийся обработки наборов данных в определенных ситуациях.

Допустим, у меня есть приложение, в котором я использую некоторые сущности. У нас есть Заказ, содержащий информацию о клиенте, крайнем сроке и т. д. Затем у нас есть сущность Сервиса, имеющая связь один ко многим с Заказом. Служба содержит свое имя. Кроме того, у нас есть сущность Rule, которая устанавливает некоторые правила относительно того, что вычитать из материального запаса. Он имеет отношение один ко многим с сервисным объектом.

Теперь мой вопрос: как справиться с ситуацией, когда я создаю заказ и сохраняю его в базе данных с его отношениями, но в то же время я не хочу, чтобы изменения вносились в объекты, которые оказались в видимая связь с сгенерированным заказом. Мне нужно относиться к Заказу и связанным с ним данным как к некоему журналу, чтобы удаление услуги из таблицы или изменение набора правил не меняло уже сгенерированные заказы, услуги и правила, которые использовались во время процесс.

Обычно я бы справился с этим, дублируя Услуги и Правила и вставляя их в новую таблицу, чтобы данные не зависели от тех, которые используются при создании Заказа. Order просто указал бы на дублированные данные вместо исходных, что решило бы мою проблему. Но это дублирование данных, и, как мне кажется, это не лучший способ.

Итак, если вы поняли мой вопрос, знаете ли вы лучшую идею для решения такой проблемы? Извините, если то, что я написал, не имеет никакого смысла. Просто скажи мне, и я постараюсь выразиться лучше.


person R3m4ke    schedule 27.01.2014    source источник
comment
Похоже, ваш заказ хочет получить снимок значений полей в другом месте в точке размещения заказа. В ваших таблицах «Сервисы» и «Правила» могут быть столбцы с номерами редакций, чтобы заказы ссылались на редакцию, а также на данные, и когда ваш пользовательский интерфейс думает, что он меняет правила или услуги, он на самом деле добавляет новые записи с более высокими номерами редакций?   -  person Craig Graham    schedule 27.01.2014
comment
Это очень интересный способ решения проблемы. Единственным недостатком этого будет тот факт, что вам придется очищать базу данных от сущностей, на которые больше не ссылаются.   -  person R3m4ke    schedule 27.01.2014
comment
Или, если эти изменения вносятся вручную, вы сохраняете их на неопределенный срок, и они становятся частью вашего управления конфигурацией (с дополнительными столбцами для отслеживания кто, когда и почему)   -  person Craig Graham    schedule 27.01.2014
comment
Я думаю, вам нужно скопировать информацию. Ценник, отображаемый в магазине, является динамическим, но цена, отображаемая в счете-фактуре, не меняется. Не нужно копировать все, только то, что нужно. Другим вариантом было бы сохранить все исторические изменения и сохранить дату AsOf. Этот заказ использует информацию AsOf этой даты.   -  person the_lotus    schedule 27.01.2014
comment
Ну, все зависит от того, насколько гибкой я хочу. Спасибо вам обоим за ответы. Вы сделали несколько действительно интересных предложений.   -  person R3m4ke    schedule 28.01.2014
comment
Вас могут заинтересовать: заказы на оптимизацию базы данных.   -  person Branko Dimitrijevic    schedule 29.01.2014


Ответы (2)


Недавно я изучал тот же случай, поэтому я хотел бы поделиться некоторыми мыслями.

Идея состоит в том, чтобы рассматривать каждую сущность, для которой требуется управление версиями, как объект и хранить в экземплярах объекта базы данных. Скажем, для сущности service это может быть представлено так:

  1. service таблица, содержащая только service_id столбца, PrimaryKey;
  2. service_state (or ..._instance) table, that contains:
    • service_id, Foreign Key to the service.service_id;
    • state_start_dt, момент времени, когда это состояние становится активным, NOT NULL;
    • state_end_dt, момент времени, когда это состояние устарело, NULLable;
    • все реальные атрибуты service;
    • Первичный ключ — service_id + state_start_dt.
  3. конечно, диапазоны state_start_dt::state_end_dt не могут перекрываться, должны быть ограничены.

Что хорошего в таком подходе?

  1. У вас есть полная история переходов состояний ваших основных объектов;
  2. Вы можете запросить систему, какой она была в данный момент времени;
  3. Доставка новой конфигурации может быть осуществлена ​​заранее путем вставки соответствующей записи (записей) с желаемыми state_start_dt штампами;
  4. Аудит изменений интегрирован в дизайн (ну, для полной трассировки требуется пара дополнительных столбцов).

Что случилось?

  1. Будет дублирование данных. Чтобы уменьшить его, обязательно разделите инстанцирующие отношения. Мол: не создавайте единую таблицу для данных о клиентах, создайте кучу таких для учетных данных, адресов, контактов, финансовой информации и т.д.
  2. Настоящий первичный ключ — service.service_id, а информация хранится в подчиненной таблице service_state. Это может привести к ситуации, когда ваша service существует, а кто-то (намеренно или по ошибке) удалил все service_state записей.
  3. Трудно решить, в какой момент времени безопасно удалять записи state в автономный архив, поскольку, пока в системе есть объекты, ссылающиеся на service, перед удалением любых записей state следует проверить даты их вступления в силу.
  4. Из-за #3 нельзя просто удалить записи из service_state. На самом деле, также неправильно полагаться на столбец state_end_dt, так как служба могла быть активна какое-то время, а затем подавлена. И запрос службы в момент, когда она была активна, должен указывать на то, что служба активна. Следовательно, требуется столбец status.

Я думаю, что, учитывая недостатки этого подхода, это довольно приятно. Хотя я хотел бы услышать некоторые комментарии с точки зрения реляционной модели — особенно о недостатках такого дизайна.

person vyegorov    schedule 28.01.2014
comment
Я бы не сказал, что это слишком усложняет проблему, но это определенно сложное решение, которое требует некоторого размышления перед фактической реализацией. Было бы полезно, если бы нам нужно было использовать эту сюжетную линию изменений. Что здесь подходит к делу. Хотя с чем я часто сталкиваюсь, так это с тем, что помимо дублирования данных мне приходится добавлять одно дополнительное поле информации после процесса генерации Заказа. Здесь мы могли бы решить эту проблему с помощью дополнительной таблицы, которая имеет отношение один к одному с service_state. При обычном дублировании данных я просто кидаю во вторую таблицу, с данными Order. - person R3m4ke; 29.01.2014

Я бы рекомендовал просто дублировать данные в отдельных таблицах моментальных снимков. Вы, безусловно, можете использовать схемы управления версиями для основных таблиц, но я бы сомневался, насколько дополнительная сложность приводит к усилиям по сокращению дублирующихся данных. Я считаю, что дополнительная сложность модели данных приводит к тому, что систему гораздо сложнее расширять. Я бы посчитал дублирующиеся данные меньшим из двух зол.

person Shane    schedule 28.01.2014