Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Организация структуры таблиц БД, скидка на товары, По партнерам, категориям, товарам 
:(
    Опции темы
Гриша
Дата 22.9.2006, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



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

Для интернет-магазина, мне необходимо разработать структуру таблиц, содержащих информацию о скидках на товары, 
для последующего расчета цены товара с учетом скидки.
:: Цена товара завист от различных опций, цвет, размер и т. д., поэтому один товар может иметь несколько цен.

Теоритические, пока что представляется так:
1) Скидка может быть установлена например только для партнера (partner_id), 
т.е. она будет действительна для всех категорий и товаров данного партнера.
2) Скидка может быть установлена например для партнера и категории товаров (partner_id, category_id),
т.е. она будет действительная для всех товаров данного партнера и категории.
3) Скидка может быть установлена для партнера, категории товара и выбранных товаров (artner_id, category_id, product_id),
т.е. она будет действительная для всех выбранных товаров данного партнера и категории.

Код

PRODUCTS
product_id | category_id | partner_id | product_name 
    1            1             1           Книга

PRICES
price_id | product_id | price
    1          1        1000.00
    2          1        1200.00


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

--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Igor_CH
Дата 22.9.2006, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 288
Регистрация: 20.3.2005

Репутация: нет
Всего: нет



Может так:

Таблица скидка

partner_id  |  category_id   |  product_id   |   скидка 
                                                                       -10
                                                                       -100
                                                                       -10%  (если отнимать в прцентах)
PM MAIL   Вверх
Гриша
Дата 22.9.2006, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



Igor_CH, спасибо за ответ.

Я также начал когда писать таблицу, потом смотрю и никак, непойму как правильно объеденить такую таблицу с таблицой товаров (PRODUCTS), и как сделать так, что если я указал, только partner_id, то category_id и product_id должен быть любые, что у меня в итоге получается при объеденение, помойму ничего хорошего.
Так меня в ступор вогнал поиск решения это задачи.
--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Vaulter
Дата 22.9.2006, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 3
Всего: 22



Гриша, делай так
если ячейка в таблице скидок 
NULL - то любые.

то есть.
partner_id  |  category_id   |  product_id   |   скидка 
1 | NULL | NULL - скидка для всего партнеру
1 | 1 | NULL - скидка для всей категории этому партнеру
NULL | NULL | 1 - скидка на товар


--------------------
PM MAIL WWW ICQ   Вверх
Гриша
Дата 23.9.2006, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



Vaulter, спасибо за ответ.

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

Вот к примеру есть такой запрос на извлечение товаров:
Код

SELECT 
    * # Перечесляю нужные поля 
FROM 
    products 
    LEFT JOIN categories on products.category_id = categories.category_id     
    LEFT JOIN prices on products.product_id = prices.product_id             
    LEFT JOIN photos on products.product_id = photos.product_id 
    # Объеденение левостороннее, потому что фотографий для товара может не быть                     
WHERE 
    # Условия, сортировка 


// Собираю массив с данными товаров 
for ($count=0; $row = mysql_fetch_assoc($result); $count++) 
{         
    $result_array[$row['product_id']] = $row; 
}


А вот как же составить запрос, чтобы извлеч и скидку?
--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Vaulter
Дата 23.9.2006, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 3
Всего: 22



SELECT 
    * # Перечесляю нужные поля 
FROM 
    products 
    LEFT JOIN categories on products.category_id = categories.category_id     
    LEFT JOIN prices on products.product_id = prices.product_id             
    LEFT JOIN photos on products.product_id = photos.product_id 
    LEFT JOIN discount on discount.category_id = products.category_id OR discount.product_id = products.product_id

    # Объеденение левостороннее, потому что фотографий для товара может не быть                     
WHERE 
    # Условия, сортировка 

смотря какая логика.


--------------------
PM MAIL WWW ICQ   Вверх
Гриша
Дата 23.9.2006, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



Vaulter, спасибо большое за ответ.

Я совсем забыл про то что при объеденение LEFT JOIN я могу, укзывать OR, AND.
Таблицы со скидками делаю так:
D
Код

ISCOUNTS (discount_id, discount) 
DISCOUNT_CATEGORY (discount_id, partner_id) 
DISCOUNT_CATEGORY (discount_id, category_id) 
DISCOUNT_PRODUCT (discount_id, product_id)


Соответвенно общий заппрос получается такой:
Код

SELECT 
    * # Перечесляю нужные поля 
FROM 
    products 
    LEFT JOIN categories on products.category_id = categories.category_id     
    LEFT JOIN prices on products.product_id = prices.product_id             
    LEFT JOIN photos on products.product_id = photos.product_id 

    LEFT JOIN discount_product on products.product_id = discount_product.product_id 
    LEFT JOIN discount_category on products.category_id = discount_category.category_id
    LEFT JOIN discount_partner on discount_partner.partner_id = discount_partner.partner_id
    LEFT JOIN discounts on discount_product.discount_id = discounts.discount_id OR 
    discount_category.discount_id = discounts.discount_id OR 
    discount_partner.discount_id = discounts.discount_id    
    # Объеденение левостороннее, потому что фотографий для товара может не быть                     
WHERE 
    # Условия, сортировка 


// Собираю массив с данными товаров 
for ($count=0; $row = mysql_fetch_assoc($result); $count++) 
{
     // Проверяю есть ли скидка  
     if(!empty($row['discount_partner']) && $row['discount_partner'] == $row['partner_id'])
            $row['price_new'] = $row['price'] - $row['price'] * $row['discount'] / 100;
    elseif(!empty($row['discount_category']) && $row['discount_category'] == $row['category_id'])
            $row['price_new'] = $row['price'] - $row['price'] * $row['discount'] / 100;
    elseif(!empty($row['discount_product']) && $row['discount_product'] == $row['product_id'])
            $row['price_new'] = $row['price'] - $row['price'] * $row['discount'] / 100;

    $row['price_new'] = (!empty($row['price_new'])) ? number_format($row['price_new'], 2) : '';   
    
    $result_array[$row['product_id']] = $row; 
}


В итоге получается, что если есть скидка на партнера (имеет больший приоритет в моем случае), значит остальные не проверяем, и т.д.
Быстренько проверил, пока все работает.
Спасибо вам большое за помощь.

Возможно вы мне сможете подсказать, насколько запрос такого рода может быть тяжелым для БД, опыта я не имею вобщем-то, поэтому незнаю запросы такого рода, с большим количество LEF JOIN, загружают БД?

--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Vaulter
Дата 23.9.2006, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 3
Всего: 22



Гриша, 
Цитата

Возможно вы мне сможете подсказать, насколько запрос такого рода может быть тяжелым для БД, опыта я не имею вобщем-то, поэтому незнаю запросы такого рода, с большим количество LEF JOIN, загружают БД?


меньше чем какие либо другие варианты. smile


--------------------
PM MAIL WWW ICQ   Вверх
Garret
Дата 23.9.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 16.9.2006
Где: Киев

Репутация: 1
Всего: 2



Загружает конкретно(4 джойна 0_О).
PM MAIL WWW ICQ   Вверх
Гриша
Дата 23.9.2006, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



Спасибо всем за ответы.

Garret, немогли бы вы пояснить 4 джойна 0_О.

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

Но случай со скидками ведь я предполагаю, что во многих случаях варианты схожи с моим, занчит это нормально?
--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Garret
Дата 24.9.2006, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 16.9.2006
Где: Киев

Репутация: 1
Всего: 2



Гриша, имел ввиду что 4 джойна это многовато, запрос будет тормозной. Я стараюсь использовать максимум 2 джойна.
PM MAIL WWW ICQ   Вверх
Vaulter
Дата 24.9.2006, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 3
Всего: 22



Garret, 
а если надо? smile


--------------------
PM MAIL WWW ICQ   Вверх
Гриша
Дата 25.9.2006, 07:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



Спасибо за ответы.

И запрос такой нужен, и чтобы небольшая нагрузка была )

Попробю поэксперементировать с кэшированием.

--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Гриша
  Дата 4.10.2006, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



Решил разделить описанный выше запрос на несколько меньших:
1) Один извлекает данные товаров
2) Второй извлекает ИД фотографий для товаров
3) Третий извлекает цену и скидку, для товаров

Третий запрос использует следующие таблицы:
Код

PRODUCTS (product_id, category_id, partner_id, product_name)
PRICES (price_id, product_id, price)

DISCOUNTS (discount_id, discount) 
DISCOUNT_CATEGORY (discount_id, partner_id) 
DISCOUNT_CATEGORY (discount_id, category_id) 
DISCOUNT_PRODUCT (discount_id, product_id


SQL запроса:
Код

SELECT    
    *    #Список столбцов
FROM 
    products
    LEFT JOIN prices ON products.product_id = prices.product_id            
    LEFT JOIN discount_product on products.product_id = discount_product.product_id 
    LEFT JOIN discount_category on products.category_id = discount_category.category_id
    LEFT JOIN discount_partner on products.partner_id = discount_partner.partner_id
    LEFT JOIN discounts on discount_product.discount_id = discounts.discount_id OR 
    discount_category.discount_id = discounts.discount_id OR 
    discount_partner.discount_id = discounts.discount_id            
WHERE
    products.product_id IN(0,5,7,8,9,10,15,13) AND
    price_default = 1 


EXPLAIN:
Код

id | select_type | table             | type | possible_keys | key         | key_len | ref         | rows | Extra  
1  | SIMPLE      | products          | ALL  | PRIMARY       | NULL        | NULL    | NULL        | 9    | Using where 
1  | SIMPLE      | discount_product  | ref  | product_id    | product_id  | 4       | product_id  | 1    |
1  | SIMPLE      | discount_category | ref  | category_id   | category_id | 4       | category_id | 1    |
1  | SIMPLE      | discount_partner  | ref  | partner_id    | partner_id  | 4       | partner_id  | 1    |
1  | SIMPLE      | prices            | ref  | product_id    | product_id  | 4       | product_id  | 1    | Using where 
1  | SIMPLE      | discounts         | ALL  | PRIMARY       | NULL        | NULL    | NULL        | 3    |   


При описании запроса видно, что таблица Products и таблица discounts просматриваются полностью.
Я полагал, что таблица discounts будет использовать индексы и полностью не будет просмтариваться.
В результате получается, что если в таблице products будет 1000 строк, а в таблице discounts будет 10 строк, то всего MySQL потребуется просмотреть 10*1000=10000 строк и т.д.

Прошу совета по оптимизации/составлению запроса.

Это сообщение отредактировал(а) Гриша - 4.10.2006, 18:50
--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
skyboy
Дата 4.10.2006, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 14
Всего: 260



зачем делаешь  "products.product_id IN(0,5,7,8,9,10,15,13)"? почему не равенство?
PM MAIL   Вверх
Гриша
Дата 4.10.2006, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



skyboy, спасибо за ответ.
Ради интереса попробовал сделать "products.product_id = 5 or products.product_id = 7" и т.д., результат один и тот же.
А IN() я использую потому, что так удобнее. Хочу вывести на странице 5 товаров, извлекаю 5 ИД, передаю их в данный запрос в функцию IN(), хочу 10 передаю 10, проще чем у меня в запросе будет 10 условий (при помощи цикал), выполняется быстрее.
На оптимизации данного запроса это не повлияет.

Это сообщение отредактировал(а) Гриша - 4.10.2006, 19:43
--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Гриша
Дата 4.10.2006, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НУС(незнаю|узнаю|создаю)
*


Профиль
Группа: Участник
Сообщений: 181
Регистрация: 12.6.2005
Где: Земля, Москва, Хр ущевка

Репутация: нет
Всего: 1



--------------------
Если долго мучиться, что-нибудь получитЬся.
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0574 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.