Подтвердить что ты не робот

Лучший шаблон для хранения (продукта) атрибутов в SQL Server

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

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

Текущее предложение состоит в том, что в основном мы будем иметь таблицу пар имя/значение, а 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
...

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

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

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

Спасибо! Ред

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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

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

Лучше нормализовать таблицу более "традиционным" способом, используя отношения "IS-A". Например, у вас могут быть Pipes, которые являются типом Продукта, но имеют еще несколько атрибутов. У вас могут быть печи, которые являются типом продукта, но еще есть еще несколько атрибутов.

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

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

Ответ 3

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

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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