Я нахожусь в процессе проектирования базы данных, и у меня есть вторые мысли о моих начальных проектных решениях ...
Типы продукции: модели, детали, комплекты запасных частей и опции.
Вариант A (первый дизайн): я планировал иметь отдельные таблицы для указанных выше типов продуктов. Я бы сказал, что около 75% полей будут одинаковыми в каждой таблице.
Я создал каждый тип продукта в виде отдельных таблиц из-за связей, которые мне нужно создать между ними. Например, модель может иметь много опций, а опция может иметь много моделей. Опция также может иметь много деталей, а деталь может иметь много опций ... и так далее ...
Вариант B: вместо отдельных таблиц я мог бы создать таблицу с именем Product, которая включает модели, детали, комплекты запасных частей и опции. Я мог бы иметь одно поле с именем type, чтобы различать модель, опции и т. Д. Я предполагаю, что недостатком является то, что несколько полей никогда не будут использоваться (оставлены пустыми) для определенных типов продуктов. Я предполагаю, что именно здесь "не лучшие практики" вступят в игру ..
Вариант B значительно уменьшит сложность дизайна БД. Мне также не пришлось бы беспокоиться о ссылках на кучу таблиц при извлечении данных для запросов ...
Ответы:
Если бы это было мое дизайнерское решение, я бы, вероятно, выбрал больше «Вариант C» (модифицированный вариант a).
Во-первых, почему бы не «Вариант B»:
Во-первых, мне нравится ясность того, что каждый продукт имеет свою собственную таблицу. Если это всего лишь одна большая таблица с полем для определения типа, связь не так ясна.
С другой стороны, стратегия индексирования всегда требует, чтобы это поле типа было указано в списке. Так как это всего 4 типа, количество элементов индекса крайне низкое (
SELECT * FROM product_table WHERE type='X'
в любом случае, в основном выполняется полное сканирование таблицы)Вариант С
Недостатком является сложность обеспечения того, чтобы избегать сирот при обновлении / удалении объектов, и первоначальная разработка запросов, использующих эти таблицы.
источник
productID
будет FK дляproduct.id
, иoptionID
является FK дляoption.id
. Вот что я имел в виду под таблицей ссылок. И да, в этом проекте необходимо разрешить одному продукту ссылаться на несколько вариантов.Я бы посоветовал вам начать с «правильной» реляционной модели, вашего варианта А. Если типичное использование этой модели ведет вас к денормализации в некоторых областях, не бойтесь делать это.
На прошлой неделе я обсуждал с коллегой, как часто дизайн схемы считается чем-то, что заложено в камень и никогда не может измениться. Странно, учитывая то, как рефакторинг является общепринятой практикой на каждом другом уровне приложения, что рефакторинг схемы базы данных все еще рассматривается как нецелесообразный.
Если интерфейс к базе данных хорошо спроектирован, то ничто не мешает вам адаптировать схему, когда вы узнаете больше о моделях использования систем.
источник
Это звучит очень похоже на Bills материалов / нескольких кардинальностей heirarcy , что Пол Нильсен описывает в главе 17 из SQL Server 2008 Библии .
Вся глава очень хорошо прочитана, а конкретный раздел, посвященный вашей проблеме «многие ко многим», можно найти на страницах 416–419.
Это лучшее обсуждение, которое я видел в отношении типа данных с разнесенными частями .
источник
Если вы можете представить себе вероятный сценарий, в котором будут частые запросы ко всем четырем типам продуктов (и мне это кажется вероятным), тогда ваш вариант B - лучший.
Вместо того, чтобы оставлять много неиспользуемых пустых полей в таблице Product, почему бы не добавить таблицу ModelProduct, таблицу PartProduct, таблицу ReplacementPartKitProduct и иметь только те поля, которые различны для этих типов в этих таблицах? Используйте для этих таблиц тот же первичный ключ, что и для таблицы Product. Присоединитесь к таблице Product и ModelProduct, если вы хотите работать с моделями. Нужно определить, является ли запись Продукта вашей Частью? Просто выполните левое соединение между Product и PartProduct, и если PartProduct. [PrimaryKey] не равен NULL, у вас есть деталь. Если это ноль, это не часть. Кроме того, вы можете добавить поле ProductType в таблицу Product.
источник