Xpoint
   [напомнить пароль]

Реализация каталога разнотипной продукции

Метки: [без меток]
2005-12-13 15:14:06 [обр] Sync[досье]

Ставится задача реализовать каталог разношерстной продукции (каждая категория товаров имеет свои характеристики, количество и тип (строка, выбор из списка, флаг и тд.)) которых заранее неизвестны.
То есть надо предоставить пользователю самому через вэб-интерфейс настраивать эти самые структуры для каждой категории товаров. Структура представляет собой набор, вида (название поля => тип поля).
Например, Цена => инпут (в базе FLOAT), описание => textarea (в базе TEXT).

Со структурами вроде все понятно, проблемы возникают при организации БД. То есть как хранить все данные о товарах и их характеристиках С ВОЗМОЖНОСТЬЮ поиска по характеристикам, группировки по ним (например все ноутбуки с диагональю 17")....

Пока из того что знаю:

  1. одна таблица на все товары с общими данными (название, цена, дата создания, описание, ID категории)

на каждую отдельную структуру - отдельная таблица (типа tovar_id(FK) provider memory cpu_type fsb)
+ возможно не очень тяжело реализовать, нет избыточности
- надо программно создавать таблицы, использовать ALTER в процессе изменения структуры.

  1. одна таблица на все товары с общими данными (название, цена, дата создания, описание, ID категории)

для всех структур делаем большую таблицу с INT и TEXT полями, по 10 на штук :)
+ легко реализовать, постоянное количество таблиц и полей ВСЕГДА.
- избыточность, раковость с точки зрения проектирования БД.

  1. одна таблица на все товары с общими данными (название, цена, дата создания, описание, ID категории)

для каждого поля (характеристики) - одна таблица
+ избыточности никакой, не надо делать ALTER, довольно прозрачный подход.
- возможно не самый легкий путь, при выборке товаров надо делать JOIN столько раз, сколько характеристик мы имеем - не затруднит лм это нашу БД?

Хотелось бы услышать еще решения данной задачи, так как думаю она довольно распространена, а я вот колеблюсь.
Спасибо.

спустя 1 час [обр] Алексей Севрюков(2/1280)[досье]

3 вариант + изменения.
Для каждой характеристики не надо делать отдельную таблицу, храните все в одной таблице.

Вы будете делать так называемый "подбор по параметрам"?

спустя 17 минут [обр] Thirteensmay(0/157)[досье]
Я тоже за 3 вариант, потому как гибко, без избыточности, и логически просто. Да, селекты будут длинноваты... но они будут логически просты !!! Алексей Севрюков[досье] я Вас не понял...
спустя 1 час 35 минут [обр] Thirteensmay(0/157)[досье]
Впрочем да... null-ы никто не отменял ;) Проще некуда.
спустя 39 минут [обр] Алексей Севрюков(2/1280)[досье]
Thirteensmay[досье] Не поняли что?
спустя 14 минут [обр] Sync[досье]

Алексей Севрюков, вы писали:
> 3 вариант + изменения.
> Для каждой характеристики не надо делать отдельную таблицу, храните все в одной таблице.

Так скорее всего не получится, разница между числовыми и нечисловыми данными у меня имеет смысл, если сортировать по цене, то 25 будет меньше чем 3... в этом то и проблема.

> Вы будете делать так называемый "подбор по параметрам"?
верно, такая функциональность ожидается.

спустя 4 минуты [обр] Sync[досье]
Thirteensmay, а ты пробовал эти запросы к таблицам с хотя бы > 1000 записей?
Учитывая что JOIN'ов будет 10-15...
Я не тестировал, признаюсь, сегодня попробую.
спустя 1 час 22 минуты [обр] AndreyF(0/1)[досье]
я бы вообще без базы делал, если товаров <1000 одного типа, св-ва товара - serialize и в файл, обработка 1000 файлов менее 1 сек., далее в массив. каждый товар в своем каталоге + картинки, никаких заморочек с навигацией.
спустя 1 час 24 минуты [обр] Thirteensmay(0/157)[досье]
Так, ладно, попорядку...
AndreyF[досье]: 1000 файлов < 1 c. ???
Алексей Севрюков[досье]: Я уже Вас понял, поэтому и пост про null-ы...
Sync[досье]: Мыслите ширше ;) Вот что Вам сказал Алексей Севрюков[досье] (если я конечно правильно его понял):
Итак: Есть только одна таблица товаров - в ней все !
Например: tovar_id, tovar_name, tovar_amount, tovar_properties1, tovar_properties2...
Если Вам нужно добавить свойство товара - добавляйте столбец, устанавливайте его тип и все !
Конечно, в этом случае у кажого товара будут все свойства - установите те которые не нужны в NULL, никаких JOIN'ов, никакой избыточности, никаких структур.
спустя 44 минуты [обр] Алексей Севрюков(2/1280)[досье]

Sync[досье] Хм, у меня все хранится так. Есть таблица групп параметров, есть таблица самих параметров, таблица связей параметров с товарами и соотвественно сама таблица товаров. Хранить тип полей (числовой или текстовой Вы можете непосредственно в группе параметров). Соотвественно если Вы будете делать выбор через несколько запросов (сперва запрашиваем группы, потом параметры) тогда Вы можете управлять типом сортировки. Сложности возникнут только если запрашивать все параметры сразу, а разбивать по группам уже скриптом, но в этом случае сортировку можно делать в том же скрипте. Либо же, добавить в таблицу параметров поле сортировки и сортировать по нему (но это уже конечно не совсем концепт).

Про 10-15 JOIN это Вы загнули, при такой структуре их будет максимум 2-3.

спустя 3 минуты [обр] Thirteensmay(0/157)[досье]
Sync[досье] кстати ! AndreyF[досье] - тоже вариант ! Выбирайте что Вам больше по душе, т.к. в плане производительности теоретически одинаково. С базами проще, но нужна СУБД, с файлами СУБД не нужна !!! - что немаловажно..., но геморойнее обеспечить туже производительность при сопоставимой функциональности (гибкости) А хотите третий вариант ? ;)
AndreyF[досье] serialize это из области XML ???
спустя 2 часа 32 минуты [обр] Sync[досье]

AndreyF[досье]
> я бы вообще без базы делал, если товаров <1000 одного типа, св-ва товара - serialize и в файл, обработка 1000 файлов менее 1 сек., далее в массив.
> каждый товар в своем каталоге + картинки, никаких заморочек с навигацией.
угу, как раз то, что мне надо! поиск, сортировку как делать? массивы лупить? не спорю, в пхп есть мощный api для этого :)

> С базами проще, но нужна СУБД, с файлами СУБД не нужна !!! - что немаловажно
нет, нет... обращение к данным в файлах не через СУБД отпадает :) зачем лишняя головная боль? да и тяжело сейчас найти хостинг без любимого мускла...

Thirteensmay[досье]
> Итак: Есть только одна таблица товаров - в ней все !
при средней "разношерстности" товаров, в такой таблице будет примерно 200 полей, не смертельно, но некрасиво.
Конечно я не рассматриваю способ, при котором идет проверка нет ли свободного для новой структуры поля из предыдущих структур и тд... это уже шаманство.

Алексей Севрюков[досье]
Толком не понял что вы имеете в виду... Но интуиция подсказывает, что у вас характеристики одного и того же товара храняться в разных строках таблиц, а не в разных столбцах. Если так, то имел неприятность так поступить, потом прищлось объединять таблицу саму с собой.
А насчет максимум 2-3 JOIN'а, то тоже не понимаю. Товар имеет 10 характеристик. Как тут обойтись двумя-тремя объединениями?

Я прихожу к выводу, что скорее всего буду заводить на каждую характеристику по таблице (tovar_id value).

спустя 4 часа 22 минуты [обр] AndreyF(0/1)[досье]

Thirteensmay[досье]serialize это из области XML ???
нет, гораздо проще и быстрее, http://ru.php.net/manual/ru/function.serialize.php, хотя если надо руками редактировать файлы или экспорт, можно и xml.

Thirteensmay[досье] 000 файлов < 1 c. ???
что, мало? я и говорю, если не предполагается большого кол-ва файлов (не более 2-3 тыс.), экспериментировал на немальньких файлах.

Sync[досье]
угу, как раз то, что мне надо! поиск, сортировку как делать? массивы лупить?
часто не сложнее sql-я

Sync[досье]
нет, нет... обращение к данным в файлах не через СУБД отпадает :) зачем лишняя головная боль? да и тяжело сейчас найти хостинг без любимого мускла...

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

спустя 5 часов [обр] Алексей Севрюков(2/1280)[досье]

Sync[досье] Без такого количества объедений все очень просто.
У нас есть id товара (он ведь точно есть), есть таблица параметров и таблица групп параметров. А так же таблица связи между параметрами и товаров. Т.е. выборка будет происходить из 4 таблиц 3 соеденениями. Причем всегда 3-мя, не зависимо от количества параметров.

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

Если все равно плохо понятно - могу днем скинуть Вам структуру, которую использую я.

спустя 3 часа 58 минут [обр] Sync[досье]
Алексей Севрюков[досье]
Со структурой вроде понятно, вот только я не настолько силен в SQL чтобы одним запросом выбрать список товаров с их характеристиками. Такую реализацию я применял ранее, и уже говорил про ее недостатки.
Или все-таки я не верно Вас понял?
спустя 3 часа 37 минут [обр] Сергей Петров(0/10)[досье]
Sync[досье] немного не так. product_id стоит поместить в таблицу params.
спустя 30 минут [обр] Алексей Севрюков(2/1280)[досье]

Сергей Петров[досье] Нет, все верно. При Вашем подходе будет дублирование информации и вообще структуру всю надо будет менять.

Sync[досье] В один запрос получится, но тогда придется гнать большой трафик от MySQL сервера и большую работать проделывать руками. Если Вам не нужен подбор по параметрам как таковой, тогда Вы можете использовать простейшую схему с 1-2 таблицами (без учета таблицы товаров). Но при таком раскладе база будет ненормализована.

Я как правило использую два запроса, первым выбирается товар, вторым категории и парараметры (с последующей дополнительной обработкой).

спустя 5 часов [обр] Старынин Валерий(0/57)[досье]
Алексей Севрюков[досье] Кидайте, пожалуйста, в тред.
спустя 2 часа 21 минуту [обр] Sync[досье]

AndreyF[досье]
>дело не в том что базу сложно найти, лень древовидную структуру в базу запихивать, плюс поля в таблицах на каждый чих заводить/редактировать, а ?>ключ массива заводиться на месте.
да нет, с этим вроде просто - используем Nested sets, а на уровне узла у нас список товаров. Работа с деревом автомитизирована полностью.
А поля на каждый чих заводить, это хорошее замечание, вот тут и боримся чтобы не делать этого или делать с наименьшими затратами.

Алексей Севрюков[досье]
Вас понято, Алексей :)
Такой подход имеет один недостаток, который я раньше считал критичным, но выходя из практических целей думаю на него забить...
ВСЕ значения параметров имеют один тип, скорее всего TEXT. То есть если поставить нереальную задачу, например отсортировать мониторы по размеру зерна :)), то это надо будет делать средствами приложения, а не субд.
В общем определился, буду делать этим способом. Для вывода списка товаров - один запрос, для детального списка - один + N, где N-число товаров, для выбора товара со всеми характеристиками - 2 запроса. Запросы шустрые, с индексами тем более. Так что вполне здравый подход.

PS: я так до сих пор и не понял как может получиться в один запрос :), даже при большом его грузе, трафике etc.

спустя 1 час 53 минуты [обр] Закиров Руслан(0/341)[досье]
спустя 5 часов [обр] Алексей Севрюков(2/1280)[досье]

Sync[досье] Про сортировку я уже писал, как минимум можно руками забивать нужный порядок сортировки. Или можно решать эту задачу средствами CMS, т.е. сама CMS будет сортировать, как это сделать я уже писал.

Одним запросом? Просто объеденяем все таблицы по ключам.

спустя 2 часа 2 минуты [обр] Sync[досье]

Закиров Руслан[досье]
спасибо за совет, вообщето проблем со скоростью выборки не возникает :)

Алексей Севрюков[досье]
Ну да, средствами цмс....
> Одним запросом? Просто объеденяем все таблицы по ключам.
То есть? у нас ВСЕГО 4 таблицы. Объединив по ключам мы получим для каждого товара несколько строк - столько, сколько характеристик. У нас же строке в таблице products соответствует несколько строк в таблице product_params. Разве что делать что-то типа
SELECT * FROM products LEFT JOIN product_params A [УСЛОВИЕ] LEFT JOIN product_params B [УСЛОВИЕ]..........

спустя 2 часа 11 минут [обр] Алексей Севрюков(2/1280)[досье]

Sync[досье] Все верно. Объеденив по ключам получим столько строк, сколько параметров. И уже потом их надо будет обрабатывать руками. Я об этом и говорил.

Почитайте ссылку, которую дал Закиров Руслан[досье]. Там как раз про то, что Вы говорите.

Powered by POEM™ Engine Copyright © 2002-2005