Лучший шаблон для хранения (продукта) атрибутов в SQL Server - PullRequest
17 голосов
/ 26 мая 2010

Мы начинаем новый проект, в котором нам нужно хранить товар и множество атрибутов товара в базе данных. Технологический стек MS SQL 2008 и Entity Framework 4.0 / LINQ для доступа к данным.

Продукты (и таблица продуктов) довольно просты (артикул, производитель, цена и т. Д.). Однако есть также много атрибутов для хранения с каждым продуктом (например, промышленные виджеты). Они могут варьироваться от цвета до сертификации (ов) до размера трубы. Каждый продукт может иметь разные атрибуты, а некоторые могут иметь кратные значения одного и того же атрибута (например, сертификаты).

Текущее предложение состоит в том, что у нас будет в основном таблица пар имя / значение с FK, возвращающим идентификатор продукта в каждой строке.

Пример таблицы атрибутов может выглядеть так:

ProdID     AttributeName     AttributeValue
123        Color             Blue
123        FittingSize       1.25
123        Certification     AS1111
123        Certification     EE2212
123        Certification     FM.3
456        Pipe              11
678        Color             Red
999        Certification     AE1111
...

Примечание. Имя атрибута, скорее всего, будет получено из справочной таблицы или перечисления.

Итак, главный вопрос здесь: это лучший способ сделать что-то подобное? Как будет выступление? Запросы будут основаны на СОЕДИНЕНИИ таблицы продуктов и атрибутов и, как правило, требуют много ГДЕ для фильтрации по определенным атрибутам - наиболее распространенным поиском будет поиск продукта на основе набора известных / желаемых атрибутов.

Если у кого-нибудь есть какие-либо предложения или более точная схема для этого типа данных, пожалуйста, сообщите мне.

Спасибо! * Ред 1016 *

Ответы [ 5 ]

16 голосов
/ 26 мая 2010

Вы собираетесь заново изобрести страшную модель EAV, Entity-Attribute-Value. Это печально известно тем, что в реальной жизни возникают проблемы по многим причинам, многие из которых описаны в ответе Дейва.

К счастью, у консультативной группы по SQL (SQLCAT) есть технический документ по теме, Рекомендации по моделированию семантических данных для повышения производительности и масштабируемости . Я очень рекомендую эту статью. К сожалению, он не предлагает панацею, решение для нарезки печенья, поскольку проблема не имеет решения. Вместо этого вы узнаете, как найти баланс между фиксированной запрашиваемой схемой и гибкой структурой EAV, баланс, который работает для вашего конкретного случая:

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

13 голосов
/ 26 мая 2010

Это будет проблематично по нескольким причинам:

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

  • Понимание того, какими будут ваши типы данных, будет сложным, когда придет время читать определенные типы данных. Вы планируете хранить это как строки? Например, DateTimes содержит больше данных, чем стандартная реализация .ToString () записывает в строку. У вас также будут проблемы, если вы попытаетесь сохранить значения с плавающей запятой.

  • Целостность данных ваших объектов находится под угрозой. Будет соблазн поместить свойства, которые должны быть просто атрибутами ваших основных таблиц продуктов, в эти «данные». Возможно, дизайн будет полусмысленным для начала, но я гарантирую вам, что через определенное время люди начнут просто бросать свойства в сумку. Тогда будет очень трудно сохранить целостность ваших объектов с такой свободно определенной структурой.

  • Ваши индексы, скорее всего, будут неоптимальными. Снова подумайте о собственности, которая должна быть на вашем столе продукта. Вместо возможности индексировать только один столбец, теперь вы будете вынуждены создавать потенциально очень большой составной индекс для вашей таблицы «type».

  • Поскольку вы, очевидно, планируете выбрасывать правильные типы данных и использовать строки, производительность запросов диапазона для числовых данных, вероятно, будет низкой.

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

Лучше нормализовать таблицу более «традиционным» способом, используя отношения «IS-A». Например, у вас могут быть Pipes, которые относятся к типу Product, но имеют еще пару атрибутов. Возможно, у вас есть Stoves, которые являются типом продукта, но имеют еще пару атрибутов.

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

IMO это дизайнерский антипаттерн. Песня сирены этой идеи заманила многих разработчиков в бездонное приложение.

4 голосов
/ 15 мая 2013

Я знаю, что это старый - однако могут быть и другие читатели ...

Я видел баланс EAV для атрибута смоделированного подхода. Ну, это все еще EAV. «EAV - это как наркотики» - это правда. Так что подумайте еще раз - и давайте будем действительно агрессивными: Мне все еще нравилось приложение супертипа, где многие таблицы используют один и тот же первичный ключ от генератора ключей. Давайте снова использовать этот. Так как насчет создания новой таблицы для каждого набора атрибутов, причем все они имеют первичные из одного и того же генератора ключей? Например. у вас будет таблица с полями «цвет, труба», другая таблица «фитинги, труба» и так далее. Требование «изменчивость атрибутов» в любом случае требует тщательно (автоматически) поддерживаемого словаря данных.

Этот подход полностью нормализован и может быть полностью автоматизирован. Вы можете поддерживать проверки, материализуются ли уже определенные наборы атрибутов в виде таблицы путем хэширования кластеров имен атрибутов, например. crc32 (нижний ('color ~ Fittingize ~ pipe')), где имена атрибутов должны быть отсортированы в алфавитном порядке. Конечно, это требует наличия хэша в словаре данных. На основе словаря данных можно искать каждый объект (используя 'UNION'), особенно если словарь данных является таблицей. Наличие словаря данных в качестве таблицы также позволяет вам использовать его первичный (суррогатный) ключ в качестве основы для уникальных имен таблиц, чтобы в итоге получить таблицы, такие как «attribute1», «attribute2», ... Большинство баз данных в настоящее время поддерживают несколько миллиардов таблиц - поэтому мы вроде как сэкономить на этом. Вы можете даже иметь каталог товаров с очень распространенными атрибутами, которые ссылаются на расширенные таблицы атрибутов.

Открытым выпуском являются наборы данных 1: n. Боюсь, вам нужно отсортировать их в отдельных таблицах. Однако это очень сильно зависит от вашего представления данных и стратегии запросов. Должны ли они всегда быть представлены в виде разделенной запятыми строки, прикрепленной к продукту, или вы хотите, например. быть в состоянии запросить все продукты определенной сертификации?

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

2 голосов
/ 26 мая 2010

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

Решение, ИМО, является гибридом.Для общих атрибутов используйте столбцы / стандартную схему.Для дополнительных, произвольных атрибутов используйте EAV.Однако правило с данными EAV состоит в том, что вы никогда и ни при каких обстоятельствах не можете написать запрос, который включает сортировку или фильтр для атрибута.Т.е. вы никогда не сможете написать Where AttributeName = 'Foo'.Часть EAV схемы представляет собой пакет данных, которые просто существуют для целей отслеживания.Фактически, я видел, как многие люди внедряли это решение, используя Xml для части EAV.В тот момент, когда кто-то хочет найти, отфильтровать, отсортировать или поместить значение EAV в определенном месте в отчете, этот атрибут должен быть повышен до столбца верхнего уровня в таблице продуктов.

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

1 голос
/ 26 мая 2010

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

Я использовал эту структуру раньше, и она работала довольно хорошо.

Как отмечает @Dave Markle, подход «имя-значение» может привести к миру боли.

...