Проблема, связанная со схемой базы данных

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

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

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

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

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

2 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

Чтобы было ясно:

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

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

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

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

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

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

Обновить

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

Первоначально я бы предложил вам иметь 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))

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

Другие вопросы по тегам