Проблема, связанная со схемой базы данных - PullRequest
4 голосов
/ 26 ноября 2010

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

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

Одна таблица продуктов с идентификатором, именем и описанием.

Одна таблица свойств с идентификатором, Product_ID, свойством и значением.

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

Ответы [ 2 ]

10 голосов
/ 26 ноября 2010

Это на самом деле движется к Шестой нормальной форме, просто такие люди, как вы, не имеющие академического или эмпирического опыта, не знают (а) его название и (б) правила и предостережения.Такие люди реализовали то, что обычно называют Entity-Attribute-Value или EAV.Если это сделано правильно, это хорошо, и есть много тысяч медицинских систем, несущих диагностическую информацию и информацию о дозировке в таких таблицах.Если это не так, то это завтрак для одной собаки в использовании и обслуживании.

  1. Сначала убедитесь, что у вас есть Product в истинном и полном 5NF.

  2. Всегда используйте полную декларативную ссылочную целостность;CHECK ограничений и RULES.

  3. Никогда не складывайте все это в одну таблицу с VARCHAR() для значения.Всегда используйте правильные (применимые) типы данных.Это означает, что у вас будет несколько таблиц, по одной на каждый тип данных, и при этом не будет потери контроля или целостности.

  4. Аналогично любым ассоциативным таблицам (где имеется множественная ссылка на другую таблицу [например, поставщик]) должен быть отдельным.

    • Я предоставляю модель данных, которая имеет полный контроль, о котором идет речь;он включает в себя простой каталог, который можно использовать как для проверки, так и для навигации.Вам необходимо добавить каждое CHECK ограничение и RULE, чтобы гарантировать, что данные и ссылочная целостность не будут потеряны.Это означает, например:
      • для столбца CPUSpeed, который хранится в ProductDecimal, CHECK, что он находится в надлежащем диапазоне значений
      • для каждого под Product table CHECK, что DataType является правильным для комбинации ProductType-ColumnNo
    • Эта структура намного лучше, чем большинство EAV, и не совсем полная 6NF.
      .
  5. Сохранить все обязательные столбцы в Product;используйте таблицы sub-Product только для необязательных столбцов.

  6. Для каждой такой таблицы (например, Product) необходимо создать представление (пунктирная линия), которое будет создавать 5NFстроки из таблиц EAV / 6NF.У вас может быть несколько видов: Product_CPU, Product_Disk.

  7. Не обновлять через вид.Сохраните все свои обновления в транзакционном режиме в сохраненном процессе и вставьте или обновите каждый из столбцов (т. Е. Таблицы Product и sub-Product, которые применимы для каждого конкретного ProductType) вместе.

  8. Гигантский?Коммерческие базы данных (не бесплатные) не имеют проблем с большими таблицами или объединениями.На самом деле это очень эффективная структура, которая позволяет выполнять очень быстрый поиск, поскольку таблицы на самом деле ориентированы на столбцы (а не на строки).Если население гигантское, то оно гигантское, сделайте свою собственную арифметику.

  9. Вам нужна еще одна таблица, таблица поиска для Property (или Атрибут).Это часть каталога, основанная на ProductType

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

Для ясности:

  • Шестая нормальная форма равна Строка состоит из первичного ключа и, самое большее, одного атрибута.

  • Это 6NF (по крайней мере для кластера таблиц продуктов), затем снова нормализуется (не в смысле обычной формы) с помощью DataType, чтобы уменьшить количество таблиц (в противном случае у вас будет одна таблица наАтрибут).

  • При этом сохраняется полный контроль над Rdb (FK, ограничения и т. Д.);тогда как обычные типы EAV не беспокоят DRI и управление.

  • Это также имеет зачатки каталога.

Ссылка на модель данных кластера продуктов

Ссылка на нотацию IDEF1X для тех, кто не знаком со стандартом реляционного моделирования.

Обновление

Вам может быть интересно это ▶ 5NF 6NF Обсуждение ◀ .Я напишу это в какой-то момент.

0 голосов
/ 26 ноября 2010

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

Однако я не заинтересован в идее сохранения значения рядом с каждым свойством как 1: 1. Лучше всего, если у вас есть таблица propertyvalue, которая связывает свойство со значением. Затем вы отказались бы от таблицы productproperty, чтобы иметь более богатую таблицу productpropertyvalue, которая могла бы полностью описать взаимосвязь между продуктом, его свойствами и их значениями.

Возможно, тогда вы могли бы иметь следующее:

product => (ID (unique key), Name, Description)
property => (ID (unique key), Description)
propertyvalue => (ID (unique key), propertyID (foreign key), value)
productpropertyvalue => (ID (unique key), productID (foreign key), propertyValueID (foreign key))

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

...