![]() |
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]() ![]() ![]() |
|
Vas |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: нет Всего: 28 |
Доброе время суток, уважаемые гуру!
Ну собственно возник вопрос, не столько по РНР, а сколько по структуре БД. т. к. БД относится к интернет-магазину, то собственно решил задать его здесь. 1. Необходимо добавить дополнительные характеристики к каждому товару, причем в зависимости от типа товара характеристики могут быть разными. 2. Также характеристика может быть прицеплена конкретно к товару, а не к его типу. 3. Каждой характеристике может быть задано несколько значений на выбор и установлено одно по-умолчанию (в идеале для разных групп товаров могут быть разные списки значений). 4. Попробовать соблюсти целостность данных на уровне БД, то бишь сделать все на внешних ключах, и при обновлении какого-то параметра, чтобы автоматом менялись значения и у всех владельцев данных опций (о как завернул, блин, ну вы меня поняли). Итак у меня пока два варианта реализации: 1. Таблица характеристик, таблица типов, таблица отношений характеристик к типам (многие ко многим), таблица отношений характеристик к товарам (многие ко многим) и таблица возможных значений. В принципе все просто. В таблице характеристик храним тип поля (список или поле ввода) и храним идентификатор значения по-умолчанию из таблицы возможных значений. Но при выборе одного товара, придется написать запрос с минимум 5-ю таблицами и связями между ними, как это отразится на производительности, всем я так понимаю ясно (индексы и внешние ключи созданы будут обязательно). Естественно здесь целостность будет поддерживаться практически полностью, изменение значения харатеристики в таблице значений автоматом отобразится на всех товарах. 2. Таблица характеристик, таблица типов, таблица отношений характеристик к типам (многие ко многим), таблица отношений характеристик к товарам (многие ко многим) и не делаем никакую таблицу значений, а значения храним в виде строки (например, HDMI;DVI:D-Sub) в таблице характеристик и при выводе преобразуем все это в массив. Все тоже просто, но в данном случае нам придется писать не идентификатор значения в таблицу характеристик товара, а конкретно значение, при этом если кто-то сделал в начале запуска проекта описание типа HDLI вместо HDMI, то все одним движением поправить будет проблематично, но зато запросы становятся проще и выигрываем в быстродействии. У кого есть опыт разработки интернет-магазинов помогите советом, какой вариант выбрать, или может еще что-то убрать или добавить? -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
Vas |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: нет Всего: 28 |
Неужто никто из здесь присутсвующих не сталкивался с проектированием БД для интернет-магазина?
-------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 14 Всего: 386 |
Интернет магазин - это немного больше, чем каталог товаров. А вопрос про каталог товаров, насколько я понял.
Разумнее начать знакомство с существующих решений e-comerse и битрикс. Могу предложить свое "вело-решение". ;) Его преимущество - компактность. Весь каталог товаров с категориями хранится в 2-х таблицах, причем каждый элемент имеет неограниченное количество свойств. Его минусы - сложно(большая нагрузка на базу) организовать поиск по атрибутам товаров. Впрочем проблема с поиском полностью та же, что и в битриксе, так как хранение свойств организовано аналогично. Для небольшого количества товаров (1-5к) с небольшим (10-20 штук) количеством свойств, вполне шустро работает. Для организации шустрого и достаточно большого каталога обычно используется nosql решения. MongoDb, например. Хотя я с ним пока не работал. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Vas |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: нет Всего: 28 |
Ну в принципе да, именно нужно расширить возможности каталога интернет-магазина ![]()
Я правильно понимаю, есть таблица товаров и есть таблица их характеристик? Но тогда возникает вопрос, как пользователь в админке добавляет одну и туже характеристику каждому товару, каждый раз пишет ее название или есть какая то хитрость?
Тоже пока не работал, но в сети много пропаганды. Но с трудом я пока верю в производительность nosql, причем где-то наталкивался на указание того, что и монгоДБ не очень шустрая если объекты обладают кучей свойств. -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
||||||
|
|||||||
Sanchezzz |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1670 Регистрация: 19.11.2006 Где: Voronezh Репутация: 1 Всего: 60 |
mongo хорошо работает причем диалект запроса можно полностью сделать схожим SQL
Mysql Структура таблиц примерно такова доп поля. id int PK -- Авто инкремент нужен индекс field_type int -- Тип свойства текст, множественный список, итд. name varchar -- Названия свойства code varcahr -- Названия поля в EN без пробелов и тире. key value таблица id int PK id_tovar int -- id товара. индекс id_type_field int -- тут id храним от доп таблицы индекс value TEXT или varchar(8000) -- значение, макс 64кб вполне достаточно. Для множественного типа списка выбора значений делается отдельная таблица которая нужна только на этапе формы. Структуру пропустим. 1 Сперва делаем поиск по таблице tovar + INNER JOIN и необходимым связкам получаем значения с лимитом 2 второй, третий запрос это получения всех значений у найденных товаров. Рекомендую сделать класс для поиска который генерировать будет вам такие запросы ну и конечно же админку Минус способа это мусорная таблица, трудность составления запросов придется написать класс который это будет облегчать и генерировать запросы. Нужна будет админка по управлению структуры. Что бы все достать нужно делать 3 запроса при поиске. Текущая нагрузка на одном проекте 3мл записей. Вроде все быстро, у вас будет меньше если чистить мусор). -------------------- Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS. |
|||
|
||||
Vas |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: нет Всего: 28 |
Sanchezzz, спс за описаниереализации, но непойму одого нюанса, в value при множественном списке что пишется, просто значения характеристики через разделитель?
-------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
Sanchezzz |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1670 Регистрация: 19.11.2006 Где: Voronezh Репутация: 1 Всего: 60 |
Значение которое выбрали.
А список из чего выбирать в отдельной таблице для таких типов полей. Списки участвуют только при заполнении можно даже рядом где значение сделать доп колонку 1 запрос это получение структуры какие типы итд у товара. 2 сам поисковый запрос с SQL_CALC_FOUND_ROWS + LIMIT для постранички 3 Когда не нужна сортировка по значениям из доп полей. Придется JOIN таблицу делать много раз с доп полям значениями все поля, которые сортируются, создавать алиасы, значения которые нужно сортировать в число нужно конвертировать для точной сортировки С конвертацией значения сортировки если не охота конвертировать то хранить значения в 3х разных колонках текстовые значения TEXT числовые INT с плавающей точкой в float. В какую колонку записывать значение и из кокой брать значений вам подскажет таблица типов доп полей товаров, также там можно запихнуть валидацию для заполнения таких полей 4 Финальный запрос это получение всех доп значений у товара по ID товара который мы получаем в 2 пункте. SELECT * FROM field_value WHERE id_tovar IN ( Полученные ID ) PS В битриксе с доп полями это ситуация обстоит так в 7 Версии дальше как Cms меня эта система не интересовала. К основной таблице отдельного контент блока происходит модификация таблицы В отдельной таблице также хранятся список доп полей. множественный списки в отдельной таблице, Значения также. При таком подходе нет гемора с сортировками и кучи JOIN таблиц выборка происходит легче. -------------------- Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS. |
|||
|
||||
ksnk |
|
||||||||||||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 14 Всего: 386 |
Сначала - немного "ядрЁных" вещей - объектная модель данных. При просмотре нужно иметь ввиду, что это предназначено для не очень большого объема данных, с не очень ветвистой структурой хранения. Понятие "не очень большой" определятся по месту. Если тормозит - значит большой ![]() Ну и писалось это из полуспортивных соображений - "а слабо весь сайт в одну таблицу уложить?". Оказалось - не слабо. только в две.... Структуры таблиц - мясная таблица
- деревянная таблица (в варианте AdjansetSets)
Конкретный тип свойства определяется по сохраненной ячейке. Длинная строка сохраняется в поле tval, короткая строка - sval, число в ival. Вероятно, имеет смысл хранить поля dval для даты и fval для плавающего, но я как то и так обошелся. При чтении свойства - тип его определяется так же. На этих таблицах навернута объектная модель данных, когда каждый объект представляется в виде массива с неопределенным количеством параметров. Каждый объект имеет ID и может иметь уникальное имя. интерфейсные методы модели - выдать объект по ID или по имени (по типу параметра числовой-строковый). Выдает объект-массив. - найти объекты по набору свойств - выдает комплект объектов, подходящих по свойствам. - сохранить массив. поля ID, name и parent воспринимаются специальным образом. Быстрый доступ к объекту возможен по ID или по имени. По ID получится так
получится массив пар имя-значение, который помещается в объект-результат. Он дополняется этим
получая поля parent и name Поиск по name примерно так-же, только сначала находим ID по имени из таблицы item_tree. Поиск по неполному набору свойств трансформируется в sql примерно таким кодом
функция _cellname по типу параметра определяет имя ячейки таблицы flesh, в которой оно должно храниться. То есть получается множество join'ов к самой таблице. Прям как в битрикс ![]() Теперь немного конкретики по каталогу товаров. Конкретный товар - массив с параметрами. У каждого товара есть параметр "main_item", который указывает на "главную карточку товара". Есть понятие "расцветки" - это товар с теми-же свойствами, но с небольшими изменениями. При сохранении конкретного свойства можно его сохранять в главную карточку или в карточку товара. При получении всех свойств, основные свойства читаются из записи и дополняются записями из главной карточки. можно автоматизировать выбор места сохранения свойств. Если свойства нет - пишем в главную карточку. Если есть и отличается - в конкретную. При определенной дисциплинированности контент-менеджера получится довольно оптимально.
пользователь указывает, что товар является "расцветкой" уже существующего товара (X). Свойство "главная карточка" объекта X копируется в свойство нового товара. и все. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
||||||||||||
|
|||||||||||||
Sanchezzz |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1670 Регистрация: 19.11.2006 Где: Voronezh Репутация: 1 Всего: 60 |
- мясная таблица
![]() Битрикс это не любовь всех программистов походу, я даже устраиваться в эти компании не иду когда слышу bitrix... Да лучше в две таблицы чем в 4000 причем это не шутка ( программист 2001 году сделал называется систему на рост)) ) -------------------- Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS. |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 14 Всего: 386 |
Да не! Нормально. Админка там довольно приличная, особенно, если персонал уже привык. Вот только сам сайт в итоге наполовину переписался на собственный движок, и ключевые данные из битриксовских структур периодически копируются в более удобные для показывания таблицы, чтобы количество join'ов сократить, а так - жить можно ![]() -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Vas |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: нет Всего: 28 |
Хорошая идея, прям наследование получается, у меня в разделах каталога ветвь используется, а вот для продукции я такого сделать не догадался надо переделать реализацию, благо вся модель вынесена в отдельные классы.
Да с битриксом не сталкивался, но и смотреть его не очень хочется. Лучше я свой "лесик" допилю до конца, тем более что 80% кода уже написано, надо слегка расширить функционал.
В целом согласен. Ну 4000 таблиц это жесть ![]() Спс всем за участие с меня "+". Теперь я больше склоняюсь к своему 2 варианту, у меня по нему получается структура почти как у Sanchezzz, только будет еще одна таблица отношений типов товаров и характеристик, в ней будут храниться общие характеристики для однотипных товаров, использоваться она будет только в админке, при добавлении товара из нее будут автоматом копироваться все характеристики в мясную таблицу ![]() -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
||||
|
|||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 14 Всего: 386 |
Мне тут вспомнился головняк, который так и не решился у меня в одном проекте. Юзеры жаловались, что сложно устанавливать скидку на 100500 товаров, если нужно установить ее один раз для какого-то производителя (одно из свойств карточки).Дело решилось тем, что админка фильтрует все нужные товары и устанавливает скопом какое то свойство для всего списка карточек. Если бы "наследование" можно было продолжить еще на несколько уровней - было бы проще в этом случае. К сожалению, каждая "итерация наследования" - это чтение карточки. Можно, наверное, состряпать правильный sql и получать все одним запросом, но у меня каждый уровень - чтение новой карточки. Так что добавление третьего уровня наследования вызвало уже заметные тормоза при фильтровании товаров, и в результате все осталось как есть. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Vas |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: нет Всего: 28 |
Можно попробовать написать функцию, которая рекрсивно будет дергать только ID всех родиельских записей, а потом банальным sql типа
Два индекса придется создать для обхода ветки ну и смотреть по планам на производительность. А вот когда придется показать свойства нескольких товаров, типа сравнения, вот тут и могут быть основные тормоза. -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
||||
|
|||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 14 Всего: 386 |
Ну да. Самый эффективный тест на производительность базы - система поиска по свойствам, обычная для e-магазинов. Пример можно посмотреть на любом крупном магазине, на ulmart например. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 3 Всего: 42 |
Почему не решил задачу в лоб? Именно установить скидку на производителя. Добавлено через 58 секунд
А я бы загнал это в полнотекстовый индекс ![]() -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | PHP: Базы Данных | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |