Страницы

Поиск по вопросам

четверг, 13 февраля 2020 г.

Составить правильную структуру БД на mySQL?

#php #mysql


Есть проект, нужно создать интернет магазин с фильтром товаров. Пример можно посмотреть
тут!. Справа видна фильтрация.

Есть некоторые догадки какую структуру сделать:

1) У каждой категории будут свои атрибуты по выборке товаров. т.е. атрибуты привязаны
к категории а не к товарам.

2) Каждый товар привязан к одной конкретной категории (телевизор к телевизору, ноутбук
к ноутбуку)

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

4) Значение атрибут мы будем хранить в отдельной таблице.

Вот как то так, ниже видно схему как я очертил ее.

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


Ответы

Ответ 1



У меня реализована похожая схема. В принципе путь правильный, однако я бы предложил рассмотреть пару вариантов, которые Ваша схема не учитывает. Скорее всего будут аттрибуты, которые одинаковы по своим параметрам для разных категорий. Например: все товары имеют размеры (ширина, высота, длина). Если Ваш магазин продает товары одной направленности (скажем, только электронику), тогда имеет смысл сделать аттрибут Brand (марка). Эти аттрибуты по своим свойствам одинаковы для всех товаров. Не важно холодильник это, или телевизор. Следуя созданной Вами структуре, для каждой категории придется создавать каждый из этих аттрибутов отдельно, что "не есть хорошо" :) Решения вижу два: 1.1 В таблице attr изменить id_category на varchar и хранить id категорий разделенные запятыми. Выборку можно делать с использование FIND_IN_SET(). Да, я знаю, что это не лучший вариант, но для маленьких магазинов сойдет. 1.2 Создать промежуточную таблицу attVsCategory, в которой хранить какой аттрибут к какой категории относится. Аттрибуты могут быть разного типа. Используя мой пример выше: размеры будут представлять из себя текстовое поле, а вот brand лучше сделать выпадающим списком. Для поддержки этого варианта нужно будет 2.1 создать таблицу типа attr_values_list, где хранить варианты аттрибутов, представленных выпадающим списком, или checkbox, или radio (короче аттрибуты с фиксированными вариантами ответов) 2.2 добавить в attr_value текстовое поле, и в нем хранить либо текстовое значение (для текстовых аттрибутов), либо id из вновь созданной таблицы attr_values_list Думаю, что сделав продуманную Вами структуру, и добавив туда указанные выше пункты, вы покроете максимум возможных вариантов описания товаров. И это, вобщем-то, будет работать для магазинов абсолютно любой индустрии. Удачи

Ответ 2



Я бы тоже составил подобную схему. Есть большой и очевидный плюс - при создании товара, можно сразу же выводить значения для параметров (которые общие для категории). Дополнение по поводу категорий. Для реализации бесконечной вложенности, можно сделать дополнительное поле integer в таблице category, которое будет внешним ключом для id категории. Так Вы сможете сделать категорию, ссылающуюся на другую (родительскую) категорию. При этом можно предусмотреть автоматическое программное копирование свойств родительских категорий. P.S. Если будет реализована бесконечная вложенность категорий, можно рассмотреть возможность слияния таблиц товаров и категорий, где признаком товара будет отсутствие дочерних элементов. Но тут важно учесть одну вещь - цену, которая может быть только у товаров, и значение которой может меняться в зависимости от разных ситуаций (скидки и т.д.)

Ответ 3



Группы товаров могут составлять иерархию. Товары могут иметь разный набор свойств, находясь в одной группе. Товары могут принадлежать нескольким группам. Значения свойств товаров должны быть из фиксированных (вероятно задаваемых глобально) списков (диапазонов). Фильтр по каталогу должно быть удобно строить. (отображение виджетов полей фильтра) Фильтр по каталогу должно быть удобно накладывать. (в идеале изменением условий в where одного и того же запроса). Если ваша структура отвечает таким требованиям (за некоторыми может быть исключениями) или может быть расширена до них (главное чтоб не переделана на другую при развитии системы), пилите. На мой взгляд вы идете правильным путем.

Ответ 4



Как уже было сказано раньше, товары и группы товаров могут иметь иерархическую структуру. Для групп товаров это дерево вида: Бытовая техника -> Крупная бытовая техника -> Стиральные машины Бытовая техника -> Крупная бытовая техника -> Посудомоечные машины Для товаров это могут быть комплектации, когда задавался подобным вопросом, особенно на сотовых телефонах было видно, что 2 смартфона, имеющих одну начинку, но различающихся стразиками или рисунком на корпусе имели разную цену. Исходя из этого, я бы предложил добавить поле parent_id в таблицы product и category, которое бы ссылалось на запись, стоящую выше в иерархии. Многие свойства общие для разных категорий товаров, например, взять смартфон, планшет и ноутбук, у всех есть габариты, вес, тактовая частота процессора. Поэтому, между продуктами и аттрибутами предлагаю сделать связь многие ко многим. Так же, иерархическую структуру могут иметь и сами свойства. Например, смартфон с того же технодома: то есть, у свойств дисплей, процессор и т.п. есть свои дочерние свойства. Т.к. отображать Вы собираетесь все значения в каком-то упорядоченном виде, стоит добавить свойствам вес, то есть, порядок отображения. Сортировать их конечно можно и по ID, но тогда при добавлении новых свойств может понадобиться перебить ID уже существующим. Если Вы собираетесь фильтры генерировать динамически, то в таблицу attr я бы предложил добавить поле тип атрибута (например, число, строка, значение из списка и т.п.), так же, полезным может оказаться добавление единиц измерения атрибутов. В общем, исходя из этих соображений, структура бы выглядела примерно так: Но при такой структуре осложняется контроль целостности данных. Возможно, имеет место, сделать, чтобы в таблице attr_val внешний ключ attr_id ссылался на таблицу category_attr Вообще, организация связи многие ко многим таблиц категория и атрибут выглядит лучше связи один ко многим, но так же, осложняет поддержку этих таблиц, да и банально первоначальное заполнение. Немного по выборке данных: Для облегчения построения дерева в таблице category можно добавить поле parents (varchar) значение которого бы имели вид: ID TITLE PARENT_ID PARENTS 1 Бытовая техника NULL NULL 2 Крупная бытовая техника 1 -1- 3 Стиральная машина 2 -1-2- 4 Посудомоечная машина 2 -1-2- Небольшая "денормализация", но облегчит выборку всех товаров родительской категории: SELECT * FROM product WHERE category_id IN (SELECT category_id FROM category WHERE parents LIKE('%-2-%')) Т.к. категорий как правило ограниченное количество, LIKE в условии не устроит большой нагрузки на БД при выборке данных. Для самих продуктов иерархия полезна тем, что для комплектаций не обязательно дублировать значения свойств. То есть, мы сначала выберем родительский продукт, в котором будет массив типа: [Частота процессора] = 20 [Ширина] = 30 [Высота] = 40 [Толщина] = 50 [Цвет] = Черный Потом выберем саму комплектацию с набором свойств, который надо переписать: [Цвет] = Розовый [Стразики] = Да И затерев нужные свойства получим конечную выборку: [Частота процессора] = 20 [Ширина] = 30 [Высота] = 40 [Толщина] = 50 [Цвет] = Розовый [Стразики] = Да Но, такой подход может осложнить фильтрацию. Извиняюсь, за огромное количество букв, надеюсь, хоть какая-то польза от них будет.

Ответ 5



Считаю что для конкретных реализаций, а не для абстрактно-универсальных, удобнее работать с классической "плоской" таблицей атрибутов товара. Она выигрывает в простоте и эффективности по сравнению с Entity-Attribute-Value. Например, если у нас есть такие категории: телефон(бренд, стомость, вес, рабочий диапазон, процессор) стиральная машина(бренд, стоимость, мощность, объем камеры) телевизор(бренд, стоимость, типа экрана, размер) то таблица товаров будет состоять из полей (бренд, стомость, вес, рабочий диапазон, процессор, мощность, объем камеры, типа экрана, размер) Аргументирую выбор технологии: Важно хранить данные в поле подходящего типа. "Цена", "Вес в граммах", "Название бренда" или "Дата появления" требуют разных типов. (В EAV как правило всё приведено к строке — возникают сложности с сортировкой и проверкой на вхождение в диапазон. А если в EAV вводить тип, то структура еще больше усложняется.) SQL-запросы для фильтров товара будут простыми и быстрыми! Набор атрибутов у разных категорий товаров в значительной степени пересекается, даже для "неродственных" товаров. Поэтому список возможных полей не очень велик. Да, неиспользуемые поля занимают какое-то место в базе, но можно объявить их nullable, тогда они будут очень компактными. (см. здесь) И вообще, место дёшево, труд до́рог! Итого, вам понадобится: таблица категорий. возможно с иерархией типа AL или NS таблица товаров с полным набором полей для всех категорий. таблица-описатель с перечислением имён полей для каждой категории На схеме fields.value_constraint содержит некую мета-информацию для валидации значений и построения форм с фильтрами. Остальное кажется и так очевидно. Дополнение: Если вам понадобится привязывать товар к нескольким категориям, добавится таблица-связка и уберется ссылка на категорию в товаре. А набор полей в таком товаре будет вычисляться как полный набор полей из каждой его категории минус дубли.

Ответ 6



Видимо, вопрос скорее не по фильтрации, а по самому способу хранения характеристик товаров. Во-первых, не стоит привязывать характеристики к конкретному разделу, потому что бывают ситуации, когда в одном разделе могут быть товары разных типов, а значит и с разными характеристиками. Во-вторых, характеристики могут быть множественными, например, у телевизоров могут быть разные порты входа/выхода - на 1 товар в 1 характеристике указывается несколько значений. В итоге надо сделать такие таблицы: список товаров (названия, описания, фото и т.д.) список типов товаров названия характеристик с привязкой к типам товаров и указанием типа характеристики (множественное/одиночное, сортировка, строка, число, файл и т.д.) значения характеристик (ID товара, ID характеристики, Значение).

Комментариев нет:

Отправить комментарий