Дизайн базы данных: круговая зависимость

представьте себе следующую базу данных:

таблица "компании" имеет поля id, name и flagship_product_id. В таблице "продукты" есть поля id, name и company_id.

компания должна иметь флагманский продукт (отношение 1:1), и все продукты имеют одну компанию (отношение 1:N).

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

Что такое хорошее решение, кроме разрешения нулевого отношения для начальной вставки?

подводя итог, компания должны есть один флагманский продукт.

7 ответов


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


вам либо придется разрешить NULLs в flagship_product, либо пересмотреть, как вы моделируете эту ситуацию. Рассмотреть вопрос о введении flagship_product как логическое поле, а не на продукт. Тогда у вас нет круговой зависимости. Или иметь поле product_type на продукте, которое может иметь такие значения, как флагман или обычный или устаревший или что-то еще. Конечно, вы должны обеспечить это, но в прошлом я нашел более чистое решение этой проблемы.


Я рекомендую использовать следующую модель данных:

С

  • COMPANY_ID pk

продукты

  • PRODUCT_ID (pk)
  • COMPANY_ID (fk)

FLAGSHIP_PRODUCTS

  • COMPANY_ID (pk, fk)
  • PRODUCT_ID (fk)

создание флагманского столбца в PRODUCTS таблица не гарантирует, что только один продукт является флагманским продуктом для данная компания, потому что:

  • уникальный ключ на флагманском столбце требует, чтобы значения отличались друг от друга
  • контрольное ограничение - это только список допустимых значений

Почему бы не поместить флагманское поле продукта в таблицу products как логическое... вы можете индексировать это и companyid и иметь довольно быстрый поиск


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

в этой лиге нет ни одной системы SQL.

редактировать

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


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

  • Создать Базу Данных
  • создание таблиц клиентов и продуктов
  • вставьте заполнитель или" фиктивную " строку в каждую, настроенную для ссылки друг на друга
  • установить ограничения FK между таблицы

после этого, когда создается клиент или продукт, если соответствующий ссылочный продукт / компания еще не создан, вы инициализировали новый элемент, чтобы указать на фиктивный placholder. Затем вы вводите этот элемент и выполняете обновление первой записи.

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


вам нужно будет разорвать цикл на отложить одно из ваших ограничений ссылочной целостности до конца сделки.

пожалуйста, google для "первоначально отложенного отсрочки".

(Не уверен, поддерживает ли InnoDB это)