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



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





  • поддержка многих видов продукции (ТВ, телефон, ПК, ...). Каждый вид продукта имеет различный набор параметров, таких как:




    • телефон будет иметь цвет, размер, вес, ОС...


    • ПК будет иметь процессор, жесткий диск, оперативную память...




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



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

758   4  

4 ответов:

у вас есть по крайней мере эти пять вариантов моделирования иерархии типов, которую вы описываете:

  • Наследование Одной Таблицы: одна таблица для всех типов товара, с достаточным количеством столбцов для хранения всех атрибутов всех типов. Это значит большое столбцов, большинство из которых имеют значение NULL в любой заданной строке.

  • Наследование Таблицы Классов: одна таблица для продуктов, хранящая атрибуты, общие для всех типов продуктов. Затем одна таблица для каждого типа продукта, хранящая атрибуты, характерные для этого типа продукта.

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

  • сериализованный LOB: одна таблица для продуктов, хранящая атрибуты, общие для всех типов продуктов. Один дополнительный столбец хранит большой двоичный объект полуструктурированные данные, в XML, YAML, JSON или каком-либо другом формате. Этот большой двоичный объект позволяет хранить атрибуты, характерные для каждого типа продукта. Вы можете использовать причудливые шаблоны дизайна, чтобы описать это, такие как фасад и сувенир. Но независимо от того, у вас есть blob атрибутов, которые не могут быть легко запрошены в SQL; вы должны вернуть весь blob обратно в приложение и отсортировать его там.

  • Объект-Атрибут-Значение: одна таблица для продуктов, и одно таблица, которая сводит атрибуты к строкам, а не столбцам. EAV не является допустимым дизайном в отношении реляционной парадигмы, но многие люди используют его в любом случае. Это "шаблон свойств", упомянутый в другом ответе. См. другие вопросы с eav tag на StackOverflow для некоторых подводных камней.

Я уже писал об этом в презентации, Расширяемое Моделирование Данных.


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

  • нет способа сделать столбец обязательным (эквивалент NOT NULL).
  • невозможно использовать типы данных SQL для проверки записей.
  • невозможно гарантировать, что имена атрибутов пишутся последовательно.
  • нет возможности поставить внешний ключ для значений любого заданного атрибута, например для таблицы подстановки.
  • получение результатов в обычной табличной компоновке является сложным и дорогостоящим, потому что для получения атрибутов из нескольких строк вам нужно сделать JOIN для каждого атрибута.

степень гибкости EAV дает вам требует жертв в других областях, вероятно, делая ваш код как сложный (или хуже), чем это было бы, чтобы решить исходную проблему в более обычной путь.

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

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

@StoneHeart

Я бы пошел сюда с EAV и MVC всю дорогу.

@Bill Karvin

вот некоторые из недостатков Подслушивание:

No way to make a column mandatory (equivalent of NOT NULL).
No way to use SQL data types to validate entries.
No way to ensure that attribute names are spelled consistently.
No way to put a foreign key on the values of any given attribute, e.g.

для таблицы подстановки.

все те вещи, которые вы упомянули здесь:

  • проверка данных
  • проверка орфографии имен атрибутов
  • обязательные столбцы/поля
  • обработка уничтожение зависимых атрибутов

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

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

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

эту проблему можно решить, сделав несколько запросов на частичные данные и обработав их в табличном макете с вашим приложением. Даже если у вас есть 600 ГБ данных продукта, вы можете обрабатывать их в пакетах, если вам нужны данные из каждой строки в этом стол.

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

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

Если вы все еще беспокоиться при выполнении операций, выполняемых приложением, вы всегда можете использовать Erlang, C++, Go Language для предварительной обработки данных, а затем просто обрабатывать оптимизированные данные дальше в своем основном приложении.

если я использую Class Table Inheritance значение:

одна таблица для продуктов, хранящая атрибуты, общие для всех типов продуктов. Затем одна таблица для каждого типа продукта, хранящая атрибуты, характерные для этого типа продукта. - Билл Карвин

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

какой план действий я должен быть на месте когда атрибут, который является общим только для 1 типа, затем становится общим для 2, затем 3 и т. д.?

например: (это просто пример, а не моя реальная проблема)

если мы продаем мебель, мы продаем стулья, светильники, диваны, телевизоры и т. д. Тип телевизора может быть единственным типом, который мы носим, который имеет энергопотребление. Так что я бы поставил на tv_type_table. Но затем мы начинаем переносить системы домашнего кинотеатра, которые также имеют power_consumption собственность. Хорошо его только один другой продукт, поэтому я добавлю это поле в stereo_type_table а так как это, вероятно, проще всего на данный момент. Но со временем, когда мы начинаем носить все больше и больше электроники, мы понимаем, что power_consumption достаточно широк, что он должен быть в main_product_table. Что же мне теперь делать?

добавить поле main_product_table. Напишите скрипт, чтобы перебрать электронику и поставить правильное значение от каждого type_table до main_product_table. Затем отбросьте этот столбец от каждого type_table.

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

вы можете иметь таблицу Product и отдельную таблицу ProductAdditionInfo с 3 столбцами: идентификатор продукта, дополнительное имя информации, дополнительное значение информации. Если цвет используется многими, но не всеми видами продуктов, вы можете иметь столбец с нулевым значением в таблице Product или просто поместить его в ProductAdditionalInfo.

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

Стив Yegge называет это свойства pattern и написал длинный пост о ее использовании.

Comments

    Ничего не найдено.