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

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

house_schema {
      id big int,
      house_height int,
      house_width int,
      house_decoration vchar(1024),
      build_date  timestamp,
      primary key id,
}

house {
      id big int,
      owner vchar(255),
      price big int,
      house_schema_id big int,
      primary key id,
      foreign key fk_house_house_schema_id (`house_schema_id`) reference `house_schema`.`id`
}

В таблице house_schema хранятся некоторые физические атрибуты house. В пользовательском интерфейсе программного обеспечения пользователи выбирают схему, затем нажимают кнопку «построить». Дом построен и хранится в house. Есть еще несколько таблиц, например house_schema, чтобы описать, как следует строить дом.

В простом дизайне внешний ключ, похоже, работает хорошо. Однако возникает проблема, когда разработчик решает удалить схему, которая, по его мнению, устарела. Уже есть несколько домов, построенных из схемы, и внешний ключ предотвращает ее удаление. Если мы изменим внешний ключ на DELETE ON CASCADE, то эти дома потеряют информацию, из которой они были построены.

Какой шаблон проектирования лучше всего подходит для решения этой проблемы? Что я могу представить, так это иметь дублирующуюся таблицу house_schema. После того, как дом будет построен, скопируйте строку в house_schema в дублирующую таблицу.

Но это приводит к множеству повторяющихся таблиц в базе данных, поскольку у меня есть несколько похожих таблиц с house_schema. Похоже, это нарушает правила нормализации базы данных.

У кого-нибудь есть хорошая идея?


person zx_wing    schedule 01.07.2012    source источник


Ответы (5)


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

Вместо фактического удаления строк в house_schema вам придется

  • добавить Active столбец в таблицу
  • установите для этого столбца значение false, если схема устарела
  • настройте свое приложение, чтобы не отображать неактивные схемы

Обратите внимание, что есть довольно много материалов о мягком удалении, как против, так и за.

По личному опыту, мы применяем мягкое удаление для выбираемых элементов (раскрывающиеся списки) в нашем основном приложении без каких-либо замеченных проблем.

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

person Lieven Keersmaekers    schedule 01.07.2012

Есть несколько возможностей:

  • У вас может быть поле «Удалено» в house_schema, которое вы отметите, чтобы указать, что схема больше не существует. Это означало бы изменение многих запросов.

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

person MPelletier    schedule 01.07.2012

В качестве простого решения вы можете добавить в house_schema флаг «удален». Таким образом вы сохраните исторические записи. При отображении пользователю доступных записей house_schema отфильтруйте не удаленные.

person Rainer Schwarze    schedule 01.07.2012

Возможно добавление «deprecated_schema», где вы просто копируете строку house_schema для удаления в устаревший раздел хранения. Вам понадобится поле для хранения исходного поля идентификатора house_schema, чтобы вы по-прежнему могли перейти к правильной записи в домашней таблице.

Затем вы можете удалить из таблицы house_schema и по-прежнему сохранять доступ к домам на основе этой схемы.

person JohnP    schedule 01.07.2012

Чтобы добавить еще одну точку зрения, считали ли вы, что, возможно, данные, хранящиеся в * house_schema *, на самом деле являются атрибутами дома и должны храниться как таковые?
Это можно рассматривать как случай сверхнормализации.

person TelJanini    schedule 02.07.2012
comment
Я храню схему в отдельной таблице, потому что это своего рода конфигурация перед постройкой дома. Пользователь выбирает конфигурацию, затем из нее строится дом, теперь конфигурация становится атрибутом дома. Но до этого это все равно не атрибут, так как есть дом. - person zx_wing; 04.07.2012