Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Архитектура каталога


Автор: Vex 5.9.2007, 21:51
Перед мной стоит задача написать каталог товаров с возможностью выбрать для каждой категории товара свои параметры. Допустим для жестких дисков это будет: наименование, цена, емкость.
для мониторов наименование, цена, диагональ. При чем пользователь может  сам создавать новые категории и названия новых реквизитов.

Сразу скажу, что число реквизитов для любого товара не должно превшать 20 например параметров. 


Таблица "Товары":

ИД
ИД_Категории
Наименование
Цена
Значение параметра 1
...
Значение параметра 20

Таблица "Структура каталога"

Ид
Наименование группы (мониторы, жесткие диски и т.д.)
Родитель (чтобы построить дерево)
Название параметра 1
...
Название параметра 20

Понятное дело, если лишние параметры будут путыми, их можно не выводить.

Это решение можно заменить лучшим? База MySQL, вложеность дерева 0-5, асортимент товара 3000.


СУВ.

Добавлено через 1 минуту и 7 секунд
То есть в товарах мы храним значения параметров, а в групах их название smile

Автор: WolfON 5.9.2007, 21:53
параметры в xml, нэ?

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

Автор: Golda 6.9.2007, 07:16
2 отдельных таблицы 

parameter_names (id, catalog_structure_id, name)
parameters (id, product_id, parameter_name_id, value)

Это лучше, чем xml, поскольку во всех полях базы будут храниться атомарные значения.


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

Автор: sTa1kEr 6.9.2007, 16:52
Vex, зависит от того, какой функционал вы будете реализовывать. Т.е. будете-ли искать/фильтровать товары по этим параметрам или только выводить. Так же важно насколько критичной для вас выборка и насколько частое обновление параметров и типов параметров.

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

Вариант WolfON самый простой. Минимальная нагрузка на БД и никаких ограничений по количиству и типу параметров и вроде бы все замечательно... но вот с поиском и фильтрацией будут проблемы (вот если бы БД была MSSQL 2005, то...).

Вариант Golda очень гибкий и универсальный, единственное, что надо учесть - это то что у всех параметров будет текстовый тип, что приведет к проблемам сортировки по числовым параметрам и прочим манипуляциям с данными. Так же в этом варианте будет очень сложная выборка (представляете какой запрос будет с мапингом 20 таблиц(параметров)!) и сложное обновление/добавление данных (тоже тяжело следить за всеми данными когда они все в куче...).
Но хотелось бы все-таки развить этот вариант smile Часть недостатков тут можно устранить при помощи вьюшек, foregin key-ев и триггеров. Смысл следующий: 
  • Во первых сделать 3-4 таблицы parameters с колонкой value разных типов (varchar, int, float...). 
  • При добавлении нового типа параметра для категории генерировать вьюшку с соответствующими параметрами и триггер, который будет добовлять строки в соответствующие таблици при добавлении нового товара.
  • Создание foregin key-сов с каскадным удалением для того, что бы при удалении товара потянул за собой все параметры.
Т.о. выборка будет "простой" из одной вьюшки, типы данных будут соответствовать реальным, добавление/удаление товаров тоже простым и так же достаточно простым будет обновление (такую вьюшку можно будет обновлять, MySQL сам разберется какую таблицу обновлять, но с ограничением на обновление одновременно одного поля). Так же сделать грамотное кэширование (что бы MySQL совсем не сошла с ума) и получаем абсолютно гибкую и удобную структуру... в теории.

Автор: Vex 7.9.2007, 18:57
А можно текстовые поля отфильтровать как числовые? Это тяжело будет?

Автор: sTa1kEr 7.9.2007, 20:26
Цитата(Vex @  7.9.2007,  18:57 Найти цитируемый пост)
А можно текстовые поля отфильтровать как числовые? Это тяжело будет? 

Можно при помощи CAST(). Это, конечно, дополнительная нагрузка на БД, но работать будет корректно.

Автор: ewolf 9.9.2007, 13:13
А может быть вместо нескольких таблиц parameters с колонкой value разных типов, сделать одну таблицу, но в ней несколько полей value разных типов? Например, value_int (типа Integer), value_double (типа double), value_string (типа string)

Автор: Golda 9.9.2007, 13:54
Я бы обошлась использованием CAST при выборках и структура упроститься. Тригер при добавлении - хорошая идея. А по поводу foreign key, sTa1kEr, Вы меня удивили. Это настолько само собой разумеющаяся вещь. Вы же не указываете отдельно, что первичные ключи желательно проставить

Автор: sTa1kEr 10.9.2007, 13:46
Цитата(ewolf @  9.9.2007,  13:13 Найти цитируемый пост)
А может быть вместо нескольких таблиц parameters с колонкой value разных типов, сделать одну таблицу, но в ней несколько полей value разных типов? Например, value_int (типа Integer), value_double (типа double), value_string (типа string) 

Да, можно бы и так сделать. Минус только один - 2 колонки из 3х будут всегда null.

Цитата(Golda @  9.9.2007,  13:54 Найти цитируемый пост)
Я бы обошлась использованием CAST при выборках и структура упроститься. 

Но тогда не будет работать update через вьюшку.

Цитата(Golda @  9.9.2007,  13:54 Найти цитируемый пост)
А по поводу foreign key, sTa1kEr, Вы меня удивили. Это настолько само собой разумеющаяся вещь.

Да, конечно smile Но для внешних ключей бывает 4 возможных реакции на обновлении и удаление. По умолчанию стоит restrict и это самый грамотный подход - не позволять удалять строки верхнего уровня. Но именно тут я предложил использовать cascade, т.к. таблица с товарами и таблица с параметрами - это по сути одно целое, но разваленное на две части для гибкости. В остальных случаях использовать каскадное удаление, имхо, нежелательно, т.к. при не осторожном использовании может привести к плачевным результатам.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)