Организация структуры БД интернет-магазина: цена товара зависит от его параметров.

Гриша К.

Новичок
Организация структуры БД интернет-магазина: цена товара зависит от его параметров.

Здравствуйте.

Есть задача: в интернет-магазине разные товары имеют разные параметры (размер, цвет и т.д.), от которых зависит цена товара.

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

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

Вариант решения (структура БД, с примером):
PHP:
PRODUCTS #таблица товаров
product_id | product_name | product_description
    1          Матрас №1        Пружинный

PARAMETERS #таблица названия параметров
parameter_id | parameter_name 
     1              Размер
     2              Цвет 

PARAMETERS_SELECT #таблица параметров для выбора
par_select_id | product_id | parameter_id | par_select_option
     1              1             1               90 x 90
     2              1             1              200 x 200
     3              1             2                Белый
     4              1             2               Голубой

PARAMETERS_PRICE #таблица цен для параметров 
par_select_id | price
     1          1200
     2          2000 
# Данная таблица сделана для того,
# чтобы устанавливать цену для тех параметров,
# от которых зависит цена товара, 
# в данном случае цены устанавливаются только для параметра - "Размер"
 

denver

?>Скриптер
И сколько же стоит 200x200 белый матрас а сколько 200х200 но голубой? Или тефтель с рисом котлета с картошкой и менять нельзя? :)

Последняя таблица вынесена зря (как для 3й (?) нормальной формы). Добисать price в предпоследнюю будет лучше. Это учитывая что "или белый или 200х200" гы :)

-~{}~ 19.06.06 22:14:

ага. "цена матраса зависит от размера"...
ну всё равно не красиво...
болячка вылезет даже для простого казалось бы SQL который будет доставать все товары + стоимость для каждого... На первый взгляд

-~{}~ 19.06.06 22:21:

Если расзличные сочетания параметров не первостепенное условие то сделать так и не морочить себе голову:
PHP:
PRODUCTS #таблица товаров 
product_id | product_name | product_description 
    1          Матрас №1        Пружинный 

PARAMETERS #таблица названия параметров 
parameter_id | product_id | parameter_name  | price
     1              1        200x200, белый     1200
     2              1        200x200, серый     1200
     3              1        100x100, белый     1000
     4              1        100x100, серый     1000
 
Re: Организация структуры БД интернет-магазина: цена товара зависит от его параметров

Автор оригинала: Гриша К.
Есть задача: в интернет-магазине разные товары имеют разные параметры (размер, цвет и т.д.), от которых зависит цена товара.
Раз товары разные (цвет, размер или еще что-то) они должны храниться как отдельные записи со своей ценой или группами цен. Другое дело если вы изготавливаете по заказу точный размер и от этого зависит цена, тогда надо определять как единицу не матрас а, например, площадь матраса.
 

Гриша К.

Новичок
denver, shtogrin - спасибо большое за ответы.

По поводу цвета матраса, это пример, хотя например есть кресла, у которых зеленый цвет сделан из ткани микрофибра (дорогая ткань), а белый - из тряпичной ткани (дешевая).

Товары разные, т.е. кресла, матрасы и т.д. (table PRODUCTS).
Например матрас может иметь параметры, размер, жесткость, обивка (цвет) - т.е. получается 3 <select> для выбора параметров, в один select я помещать не хочу.
Как пример приведу страницу: http://magazin.pozvonochnik.info/pages/sealy/sealy5.php - красиво только снаружи.

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

denver

?>Скриптер
Ну тогда в идеале для каждой "меры" сделать таблицу, как Star Schema. Типа:

PHP:
TABLE product (
product_id INT AUTOINCREMENT PRIMARY,
name VARCHAR(50),
description TEXT
)

TABLE color (
color_id INT AUTOINCREMENT  PRIMARY,
color VARCHAR(50)
)

TABLE size (
size_id INT AUTOINCREMENT  PRIMARY,
width INT,
height INT
)

...

TABLE weight (
weight_id INTEGER AUTOINCREMENT  PRIMARY,
color VARCHAR(50)
)

...

главная таблица объединяет все дименшыны + некую(-кие) характеристику(-и) (цена в данном случае) для их сочетания:

TABLE prices (
product_id INT,
color_id INT,
size_id INT,
...
weight_id INT,
price FLOAT
PRIMARY KEY (product_id, color_id, size_id, ..., weight_id)
)
При каждом новом дименшне придется менять структуру, но таких характеристик раз-два и обсчелся...

ЗЫ. Это мощно зато паттерн :) ... можно и попроще, если в главной хранить не айдишники дименшнсов а прямо значения.
 

Гриша К.

Новичок
denver, спасибо большое за ответ.
Вот точно такую же схему я придумал сначала, но по опыту я знаю, что характеристик товаров, будет больше.
Поэтому я начал искать другие схемы (при которых например можно легко добовлять новые характеристики PARAMETERS).

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

И ведь как назло такие схемы я ниразу нигде не видел, только у себя на сайте.
 

denver

?>Скриптер
Выбирайте что-то посередине и будет вам счастье :)
ЗЫ Характеристики можно сразу все и продумать
(накрайняк, да, добавить с значением 0 по дефолту)
Хотя что-ж это за матрасы с десятком характеристик? :D
 
Не нужно усложнять. Каждый вариант товара с разной ценой - это отдельный товар.

Товары со сходными характеристиками - группа товаров.
 

Гриша К.

Новичок
denver, Алексей Пешков - спасибо большое за ответы.

В инетрнет-магазине есть разные товары: орт. изделия, орт. матрасы, орт. кресла и т.д., у каждого товара могут быть свои параметры, независимо от группы товара (http://www.magazin.pozvonochnik.info/pages/emt/orto/neck.php#phila).
Имея опыт работы в данной области, я могу сказать, что предугадать характеристики не получится (в новом поступление характеристики уже другие).

Сейчас я придумал вот такой вариант:
В приведенной структуер БД (http://phpclub.ru/talk/showthread.php?postid=622637#post622637),
изменяю последнюю таблицу:
PHP:
PARAMETERS_PRICE #таблица цен для параметров 
par_select_group | price
     1_3           1200  # размер 90 x 90, цвет белый - цена 1200
     1_4           1200  # размер 90 x 90, цвет голубой - цена 1200
     2_3           2000  # размер 200 x 200, цвет белый - цена 2000
     2_4           2000  # размер 200 x 200, цвет голубой - цена 2000
# par_select_group - содержит группу параметров (par_select_id),
# из таблицы PARAMETERS_SELECT
Буду пробовать реализовать данную структуру, в результате наверное смогу увидеть получается ли то, что необходимо или нет.

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

denver

?>Скриптер
Гриша К.
Посмотри может филд тайп SET, par_select_group в твоем последнем примере в корне не правильный как для реляционной БД.

Алексей Пешков тоже верно предлагает.
 

Navarro

Новичок
TABLE `Products` (
`Product_id` int(10) unsigned NOT NULL default '0',
`Type_id` int(10) unsigned NOT NULL default '0',
`Weight` int(10) unsigned NOT NULL default '0',
`Height` int(10) unsigned NOT NULL default '0',
`Cover_id` int(10) unsigned NOT NULL default '0',
`Color_id` int(10) unsigned NOT NULL default '0',
`Options` int(10) unsigned NOT NULL default '0',
`Price` float NOT NULL default '0'
)

TABLE `Product_desc` (
`Product_id` int(10) unsigned NOT NULL default '0',
`Name` char(255) NOT NULL default '',
`Description` char(255) NOT NULL default ''
)

TABLE `Cover` (
`Cover_id` int(10) unsigned NOT NULL default '0',
`Cover_name` char(255) NOT NULL default ''
)

TABLE `Color` (
`Color_id` int(10) unsigned NOT NULL default '0',
`Color_name` char(255) NOT NULL default ''
)

TABLE `Product_Options` (
`Type_id` int(10) unsigned NOT NULL default '0',
`Options_id` int(10) unsigned NOT NULL default '0',
`Description_1` char(255) NOT NULL default '',
`Description_2` char(255) NOT NULL default ''
)

INSERT INTO `Product_Options` VALUES (1, 1, 'Вертикальный взлет', '');
INSERT INTO `Product_Options` VALUES (1, 2, 'Запасной парашют', '');
INSERT INTO `Product_Options` VALUES (1, 4, 'Защита от скрипа', '');
INSERT INTO `Product_Options` VALUES (1, 8, 'Откидная спинка', '');


Т.е в данном случае ты можешь описать для каждого типа 32 опции
 

denver

?>Скриптер
Navarro
Вся эта бинарная фигня с 1/2/4/8/... решается использованием SET
 

Гриша К.

Новичок
denver, Navarro - спасибо большое за ответы.

Navarro, возможно я не совсем понял ваш пример:

TABLE `Product_desc` - название, описание товара.
TABLE `Cover` - обложка (фотография) товара.
TABLE `Color`- цвет товара
TABLE `Product_Options`- опции товара, т.е. можно выбирать, например для матраса, покрывало или подушку, и т.д.
TABLE `Products`- объединяет все таблицы, + в ней же опеределяется размер товара. Что за поле options?

В данном случае получается, что я определяю тип товара, для него например делаю список опций жесткость: мягкий, жесткий, очень жесткий.
Тип товара определяется для сходих товаров, у которых к примеру вся жесткость соотвествует схеме: L, X, XXL
А зачем тогда делать таблицу цвет и размер?
И непонятно, то, что если цена товара зависит от разных опций, в данном случае цена же определяется для одной опции, т.е. если цена товара зависит от размера и от цвета, то я не смогу это реализовать?

Вот не совсем разобрался с вашей схемой. Может быть вы могли бы, написать некоторые поянения?


Алексей Пешков, вашу схему я понимаю так, что вы предлогаете например 2 матраса с рамзерами 90x90 и 200x200 определять как разные товары, т.е. для них разное описание и т.д. Либо я вас неправильно понял?
[/php]
 

asm

Пофигист
PHP:
PRODUCTS (
    product_id, 
    product_name,
    product_description
    price
)

OPTIONS (
    options_id,
    option_group_id,
    options_name
)

OPTIONS_GROUP (
    grouop_id,
    group_name
)

PRODUCTS_OPTIONS(
    product_option_id,
    product_id,
    options_id,
    option_price
)
 

Гриша К.

Новичок
asm, спасибо за ответ.

Мне совсем не понятная ваша схема, не могли бы поянсить.
 

Гриша К.

Новичок
asm,

Я разбирал вашу схему, ниже привожу пример.
(1) поле price в таблице PRODUCTS, это я так понимаю для товаров у котрых не будет опций?
(2) кол-во опций получается неограниченное (это +), но цена матраса зависит и от размера и от цвета, то в данной схеме это не применить:
90x90 - белый = 1050
90x90 - голубой = 1100
200x200 - белый = 1150
200x200 - голубой = 1200

PHP:
PRODUCTS
product_id | product_name | product_description | price 
    1          Матрас №1     Описание матраса      0

OPTIONS
options_id | option_group_id | options_name
    1              1               90x90
    2              1              200x200
    3              2               Белый
    4              2              Голубой


OPTIONS_GROUP
group_id | group_name
    1        Размер
    2        Цвет

PRODUCTS_OPTIONS
product_option_id | product_id | options_id | option_price 
       1                1            1            1000
       2                1            2            1000
       3                1            3            1200
       4                1            4            1200
 

asm

Пофигист
option_price - это цена фичи а не товара с фичей (может быть отрицательной :))

-~{}~ 21.06.06 18:50:

PRODUCTS
product_id | product_name | product_description | price
1 Матрас №1 Описание матраса 1050

OPTIONS
options_id | option_group_id | options_name
1 1 90x90
2 1 200x200
3 2 Белый
4 2 Голубой


OPTIONS_GROUP
group_id | group_name
1 Размер
2 Цвет

PRODUCTS_OPTIONS
product_option_id | product_id | options_id | option_price
1 1 1 0
2 1 2 150
3 1 3 0
4 1 4 50
 

Гриша К.

Новичок
asm, спасибо за ответ.
По данной схеме нельзя установить цены и для размера и цвета одновременно, цена устанваливается либо для размера, либо для цвета?
Либо я совсем вас не понимаю.

Мне вот подсказали вот такую схему (покраней мере здесь число опций неограничено и цены определяются для сочитания опций, хотя возможно сома структура не очень хороша в плане объединения таблиц и скорости, над этим буду думать):

PHP:
PRODUCTS # товары
product_id | product_name | product_description
     1          Товар            Описание

OPTION_NAME # названия опций
option_name_id | option_name 
      1            Размер
      2            Цвет

OPTIONS # значения опций
option_id | option_name_id |option_value 
    1            1            80x90
    2            1            120x90
    3            2            Белый
    4            2            Голубой

PRICES # цены
price_id | product_id | price
   1           1         100
   2           1         150
   3           1         200
   4           1         250

OPTION_PRICE # сочитание опций и цен
option_id | price_id
    1          1        # Размер: 80x90 +     
    3          1        # + Цвет: Белый = 100
    1          2        # Размер: 80x90 +
    4          2        # + Цвет: Голубой = 150
    2          3        # Размер: 120x90 +
    3          3        # + Цвет: Белый = 200
    2          4        # Размер: 120x90 +
    4          4        # + Цвет: Голубой = 250
 

Navarro

Новичок
2 Гриша К.
Вообще-то под полем cover я понимал покрытие используемое для товара. :) (микрофибра, тряпичная ткань )

Поле Options содержит сумму айдишников выбранных опций
т.е если Options=9, то у товара есть 'Вертикальный взлет' и 'откидная спинка' (1+8) (Описываеться в таблице Product_options)

То, что denver предлагал использовать поле SET имеет смысл только в том случае, если у тебя суммарное количество опций для всех типов товара никогда не будет превышать 64 пункта (8байт максимум), ибо это ограничение накладываемое на поле SET.
В моем примере я выделил под поле Options 4 байта, что позволяет описать 32 опции для каждого типа товара. Если этого не хватает, то можно использовать 8 байтовое поле, что позволит, описать 64 (8x8) опции. По аналогии, можно спуститься до однобайтового числа.

Надеюсь, ты понимаешь. что это всего-лишь пример и он наврядли подойдет тебе на 100%.
 
Сверху