Топ контрибуторов
loading
loading
Знаете ли Вы, что

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

Лента обновлений
ссылка 14:57:26
Комментарий от sashka228:
согласна
ссылка 14:56:54
Комментарий от sashka228:
#ресоурсескотився
ссылка 14:54:17
Комментарий от sashka228:
yep.
ссылка 14:12:03
Добавлен вопрос в тест C++ - Средний уровень
ссылка 14:00:35
Комментарий от Anton_2015:
Гарне питання
Статистика

Тестов: 153, вопросов: 8596. Пройдено: 445772 / 2188317.

Архитектура БД интернет-магазина, для хранения характеристик товара

head tail Статья
категория
Базы данных
дата06.02.2013
авторc_k_rim
голосов6

Суть задачи

Все проще показывать на примере, вот и я возьму, абстрактный магазин, занимающийся, скажем, металлопрокатом. Необходимый и достаточный минимум в моём воображаемом магазине - две рубрики - трубы профильные (прямоугольные) и круглые.


Рассмотрим характеристики товаров в этих разделах:
Труба алюминиевая круглаяТруба алюминиевая профильная
ДиаметрДлина
ТолщинаШирина
Марка алюминияТолщина

Марка алюминия

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

Далее стоит заметить так же, что тип, характеристики может быть различный. К примеру, атрибуты "Диаметр", "Толщина", "Длинна", "Ширина", в случае с нашими трубами, могут принимать любые числовые, в том числе и дробные (foat) значения. А вот свойство "Марка алюминия" - это строка. Но, заглядывая вперед, лучше не строка, а "списковый" тип. Поскольку необходимо понимать, что "списковые" значения проще сортировать, вести по ним поиск и прочее.

Схема

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

К делу


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


После того, как мы определились (в примере) с атрибутами и их типами (конечно же не со всеми, но в качестве примера два - дробные атрибуты и списоквые, нам подойдут), можно приступить к первой таблице - таблице групп атрибутов. Вот она:


В комментариях "ИД" - уникальный идентификатор. На этом этапе, никаких пояснений, уверен, давать не стоит. Двигаемся дальше - таблица самих характеристик. Таким образом атрибуты выглядят на моем гипотетическом сайте в панели администрирования:



Не обращайте внимания на функционал, просто приятней, думаю, когда перед глазами есть пример из практики. И так, сама таблица атрибутов может иметь подобную структуру:



Обратите небольшое внимание на колонку таблицы  "is_rangeable". Она на изображении только из-за того, что мой пример - частный случай. И для "обычного" интернет-магазина, думаю, не пригодится. А если и понадобиться использовать атрибуты-диапазоны, Вам придется додумать их архитектуру самостоятельно. Поэтому, просто "забудем" о ней =)Первые 2 колонки - элементарно. Уникальный идентификатор характеристики, уникальный идентификатор рубрики характеристик (группы атрибутов) соответственно. Таким образом, получаем хранение каждого атрибута в своей определенной группе.
"name" - название. Дальше.
"type", тип - это идентификатор типа атрибута (помните, мы рассматриваем дробные и списковые атрибуты). Поскольку типы атрибутов конечны и не могут создаваться динамически - они "вшиты" в "движок" сайта, поэтому поле "type" - не ссылка на отдельную таблицу в БД, а просто числовой номер.

Поле "unit_id" - вот это уже ссылка на отдельную таблицу в БД, где хранятся все возможные на сайте единицы измерения. Казалось бы, довольно глупо создавать отдельную таблицу для этих целей и просто сделать поле строковым. Однако, уверяю, она довольно полезна по двум причинам. Первое - унификация. Если два атрибута будут иметь единицу измерения миллиметры, в итоге, после создания оных атрибутов, благодаря внимательному контент-менеджеру, может оказаться, что один имеет единицу измерения "мм" , другой "мм.", т.е. с точкой на конце. Крайне не красиво будет смотреться это на сайте. Вторая причина, это быстрое переименование. Захотели, что бы вместо "кв.м" (метр квадратный) на сайте единица отображалась как М2 - изменили в одном месте и готово =)

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

Поле "ordering" Сортировка атрибута. Но не для каждой рубрики, естественно, а просто в списке атрибутов у указанной группы в панели администрирования. Для удобства.


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



Все просто, как бы не казалось сложным =) Для каждого раздела каталога (о иерархии упомяну мгновеньем позже), задается "привязка" атрибутов. На практике, в данном конкретном примере, это звучало бы так: К разделу каталога "Труба алюминиевая круглая", будут привязаны атрибуты "Марка алюминия", "Отношение длина\вес", "Диаметр", "Толщина". Отсортированы характеристики (обратите внимание на правую часть изображения) будут в таком-то порядке.
Что бы не путаться, про надпись "Список полного листа атрибутов", я скажу ниже.
Таблиц, которые отвечают за привязку атрибутов к рубрикам стоит сделать целых две. И вот почему. В одной таблице будут храниться "настоящие" (так и не смог подобрать нормального слова) привязки. То есть, те, которые мы привязали "в ручную". А в другой - с генерированные привязки с учетом иерархии. Для того, что бы объяснить о чем речь, сделаю небольшое отступление. Возьмем еще один абстрактный интернет-магазин, в котором есть раздел, скажем, "Тазы", для всех-всех товаров в этой и дочерних рубриках есть атрибут "Ёмкость". Но в подразделе "С ручками", необходима еще одна характеристика "Удобность ухвата ручки".
Так вот, что бы не приходилось для всех "конечных", "не родительских" рубрик постоянно указывать одни и те же характеристики, необходимо продумать архитектуру, при которой атрибут "Ёмкость" можно было бы привязать к родительскому разделу, а в дочернем разделе уже был бы такой атрибут. И, да, он был бы "read-only", т.е. его нельзя было бы отвязать. Поскольку, это просто не правильно продуманная иерархия каталога, или свойств товаров в рубриках.
Лирическое отступление закончено, теперь  вернемся к таблицам. В одной будут, как я уже писал выше, храниться "привязанные по-настоящему" атрибуты, а во второй "с генерированные с учетом иерархии". Таблицы.
Первая:


Вторая, с генерированная:



Возникает один вопрос - поле "vis_mode". Я выше обещал о рассказать о том, что же за надпись "Список полного листа атрибутов". Я не обманул. В этих двух таблицах предусмотрено несколько режимов вывода атрибутов товара. Это очень полезная вещь, как показала тысяча летная практика создания интернет-магазинов. Первый режим вывода атрибутов - для списка товаров в рубрике. Второй (главный) - общий список атрибутов у товара, для вывода на странице товара. Опять пример. В разделе "Труба круглая" выводится список товаров - труб. В этом огромном списке важна экономия места, ёмкость информации, поэтому некоторые характеристики товара, марка алюминия, к примеру, в этом списке, можно опустить. Для того, что бы в списке товаров рубрики выводились одни атрибуты, укороченный набор, так сказать, а в карточке товара, уже полный список атрибутов - стоит создать два режима вывода. Именно для этого и существует поле "vis_mode".
Вот небольшой пример из практики, как это может выглядеть в панели администрирования (к сожалению не в тематике абстрактного магазина металлопроката)


На примере видно, что есть "Главный" (или полный) список всех характеристик, но же "Список атрибутов в карточке товара". Есть режим для списка товаров, есть список атрибутов для фильтрации. Так же я обвел черным маркером еще один момент  - Атрибут "Interio" будет присутствовать у всех товаров в данном редактируемом разделе. Но и атрибут "Волховец" так же, поскольку эта привязка наследуется от родительской рубрики каталога.

Подведем промежуточный итог.
Имеет таблицу, которая хранит в себе список групп атрибутов (кстати, на изображении чуть выше, это группы атрибутов "Модель двери", "Цвет двери" и т.д.)
Таблицу, хранящую атрибуты. Их имена, номера, тип, состояние (статус).
Имеем две таблицы привязки атрибутов к рубрике каталога. Одна хранит данные "ручной привязки" (и их терять нельзя, как же мы тогда будем все это дело редактировать), вторая - с генерированная таблица привязки всех атрибутов ко всем рубрикам, в зависимости от иерархий разделов каталога. Так же таблицы отвечают за режим вывода списка атрибутов.

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


Опять таки, для примера. Хранить данные (значения) целесообразно в разных таблицах, в зависимости от их типа. Поскольку рассматривается только два - дробные и списковые атрибуты, покажу только эти две таблицы. Если бы, к примеру, были бы текстовые атрибуты, пришлось бы делать три. Но суть уловить легко.
И так, начнем с простой. Хранение значений дробных (float) чисел:

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

Отличие одно. поле "value" хранит не конкретное значение, а идентификатор на него из списка значений атрибутов. Что бы статья выглядела целостной, я и пример и таблицу для списковых атрибутов покажу. Так это выглядит в панели администрирования:


Сама структура таблицы для хранения списка значений атрибута элементарна:

На этом все.

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

Если Вам понравилась статья, проголосуйте за нее

Голосов: 6  loading...
AlexVovolka   AleXXey   SichikUA   Timoha_bs   teland94   kvinz