Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

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

Сообщения:  [1-7] 

 
 автор: Sfinks   (05.11.2012 в 18:43)   письмо автору
 
   для: sanekdi   (05.11.2012 в 18:36)
 

Не забудьте, плиз! Будет интересно узнать! =)

  Ответить  
 
 автор: Sfinks   (05.11.2012 в 18:41)   письмо автору
 
   для: Sfinks   (05.11.2012 в 18:15)
 

Единственное, что приходит в голову - сделать таблицу типом MEMORY.
Если включить профилирование запроса - видно, что 75% времени тратится на открытие таблиц, т.е. на чтение данных с диска.
При переключении с MyISAM на MEMORY это значение падает до 6%.
И общее время выполнения скрипта (с представленным дампом) падает с 2.5 милисекунд, до 0.67
Но это только при первом обращении.
Если подобные запросы выполняются постоянно, то таблица постоянно в кеше и время выполнения и там и там нивелируется к ~0.5мс.

  Ответить  
 
 автор: sanekdi   (05.11.2012 в 18:36)   письмо автору
 
   для: Sfinks   (05.11.2012 в 18:15)
 

Спасибо, за ответ ))) меня остановило наличие количество конструкции join, реально их может быть до 50, я задумался о структуре БД вообще правильная ли она? Сейчас вы меня успокоили я реально попробую данную структуру на сервере, после этого отпишусь Вам тормозит сервер БД или нет.

  Ответить  
 
 автор: Sfinks   (05.11.2012 в 18:15)   письмо автору
 
   для: sanekdi   (05.11.2012 в 17:29)
 

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

Единственное, что в этом запросе лишнее - Это DISTINCT.
У вас в shop_product_attribute_value все 3 поля - это PK, а следовательно уникальны. Следовательно при умножении shop_product на shop_product_attribute_value с WHERE по всем 3ем полям дублей никак не появится.

В остальном все нормально и EXPLAIN запроса выглядит очень красиво.

Возможно вам запрос кажется сильно тяжелым, т,к. вы не совсем правильно понимаете ход его работы?
Этот же запрос можно изобразить более логично:
SELECT a.* FROM shop_product a
JOIN shop_product_attribute_value a1 ON a.id_product=a1.id_product AND a1.id_attribute=1 AND a1.id_value=1
JOIN shop_product_attribute_value a2 ON a.id_product=a2.id_product AND a2.id_attribute=3 AND a2.id_value=8
JOIN shop_product_attribute_value a3 ON a.id_product=a3.id_product AND a3.id_attribute=2 AND a3.id_value=5

Смотрите. целые таблицы не перемножаются. Перемножаются обмылки от них, тем самым еще больше смыливаясь.
При чем все фильтры по PK.
В эксплэйне вообще в каждом подзапросе по 1 строке остается.
А в результате 1*1*1*1=1.
Ну допустим тут дамп маленький.
Допустим в реале у вас от А1 останется 200 строк.
Джойним их к А и снова в результате 200 строк.
От А2 останется пусть 300 строк.
Джойним их к А. Но у нас же INNER JOIN, а не CROSS JOIN. Следовательно результат еще уменьшается. Уже 70 строк остается.
Потом тоже с А3.

  Ответить  
 
 автор: sanekdi   (05.11.2012 в 17:29)   письмо автору
 
   для: Sfinks   (05.11.2012 в 16:59)
 

Вот запрос, по нему вернется флешка 2гб, белого цвета, весом 80гр

/*<?*/ 
SELECT DISTINCT shop_product.*
    
FROM `shop_product_attribute_value` AS a1
        INNER JOIN 
`shop_productUSING(id_product)        
        
INNER JOIN `shop_product_attribute_value` AS a2 USING(id_product)
        
INNER JOIN `shop_product_attribute_value` AS a3 USING(id_product)
    
WHERE 
        a1
.id_attribute=AND a1.id_value=AND 
        
a2.id_attribute=AND a2.id_value=AND
        
a3.id_attribute=AND a3.id_value=5


Такой тип запроса, предполагает много join - ов и join будет больше в зависимости чем больше будет атрибутов и выбранных в них значений, но другая структура БД в голову не приходит, может подскажите?

  Ответить  
 
 автор: Sfinks   (05.11.2012 в 16:59)   письмо автору
 
   для: sanekdi   (05.11.2012 в 15:21)
 

> Суть проблемы: возникает сложные запросы для выборки товаров по атрибутам и их значениям
Это плата за универсальность. Запросы по любому будут сложные.

К сожалению я пока на практике не пользовался такой структурой.
Может вы приведете пример сложного запроса, который особо нагружает БД?
Может он кроме того что сложен еще и неправильно составлен....

  Ответить  
 
 автор: sanekdi   (05.11.2012 в 15:21)   письмо автору
 
 

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

Таблица атрибутов


/*<?*/ 
CREATE TABLE IF NOT EXISTS `shop_attributes` (
  `
id_attributeint(11NOT NULL AUTO_INCREMENT,
  `
name_attributevarchar(128NOT NULL,
  `
type_inputenum('select','checbox'NOT NULL DEFAULT 'select',
  
PRIMARY KEY (`id_attribute`)
ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=;

--
-- 
Dumping data for table `shop_attributes`
--

INSERT INTO `shop_attributes` (`id_attribute`, `name_attribute`, `type_input`) VALUES
(1'Память''select'),
(
2'Вес''select'),
(
3'Цвет''select');



Таблица значений атрибутов


/*<?*/ 
CREATE TABLE IF NOT EXISTS `shop_attribute_value` (
  `
id_valueint(11NOT NULL AUTO_INCREMENT,
  `
attribute_valuevarchar(128NOT NULL,
  
PRIMARY KEY (`id_value`),
  
UNIQUE KEY `attributte_value` (`attribute_value`)
ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;

--
-- 
Dumping data for table `shop_attribute_value`
--

INSERT INTO `shop_attribute_value` (`id_value`, `attribute_value`) VALUES
(1'2гб'),
(
2'4гб'),
(
3'8гб'),
(
4'16гб'),
(
5'80 гр'),
(
6'120 гр'),
(
7'Черный'),
(
8'Белый'),
(
9'Сниний'),
(
10'красный');



таблица связей атрибутов и значений

/*<?*/ 
CREATE TABLE IF NOT EXISTS `shop_attribute_to_value` (
  `
id_attributeint(11NOT NULL,
  `
id_valueint(11NOT NULL,
  
PRIMARY KEY (`id_attribute`,`id_value`),
  
KEY `id_attribute` (`id_attribute`),
  
KEY `id_value` (`id_value`)
ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- 
Dumping data for table `shop_attribute_to_value`
--

INSERT INTO `shop_attribute_to_value` (`id_attribute`, `id_value`) VALUES
(11),
(
12),
(
13),
(
14),
(
25),
(
26),
(
37),
(
38),
(
39),
(
310);



таблица товаров


/*<?*/ 
CREATE TABLE IF NOT EXISTS `shop_product` (
  `
id_productint(11NOT NULL AUTO_INCREMENT,
  `
namevarchar(255NOT NULL,
  `
titlevarchar(255NOT NULL,
  `
meta_kvarchar(255NOT NULL,
  `
meta_dvarchar(255NOT NULL,
  `
pricefloat(8,2NOT NULL,
  `
newenum('no','yes'NOT NULL,
  `
hideenum('hide','show'NOT NULL,
  `
date_adddatetime NOT NULL,
  
PRIMARY KEY (`id_product`)
ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=;


INSERT INTO `shop_product` (`id_product`, `name`, `title`, `meta_k`, `meta_d`, `price`, `new`, `hide`, `date_add`) VALUES
(1'Flash Kingston 2гб''Flash Kingston 2гб'''''100.00'yes''show''2012-11-05 16:48:37'),
(
2'Flash Kingston 4гб''Flash Kingston 4гб'''''200.00'yes''show''2012-11-05 16:49:04'),
(
3'Flash Matrix 2гб''Flash Matrix 2гб'''''120.00'yes''show''2012-11-05 16:50:21'),
(
4'Flash Matrix 4гб''Flash Matrix 4гб'''''180.00'yes''show''2012-11-05 16:51:31');


таблица связей между атрибута, значением атрибутов, и товарами


/*<?*/ 
CREATE TABLE IF NOT EXISTS `shop_product_attribute_value` (
  `
id_productint(11NOT NULL,
  `
id_attributeint(11NOT NULL,
  `
id_valueint(11NOT NULL,
  
PRIMARY KEY (`id_product`,`id_attribute`,`id_value`),
  
KEY `id_product` (`id_product`),
  
KEY `id_value` (`id_value`),
  
KEY `id_attribute` (`id_attribute`)
ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- 
Dumping data for table `shop_product_attribute_value`
--

INSERT INTO `shop_product_attribute_value` (`id_product`, `id_attribute`, `id_value`) VALUES
(111),
(
125),
(
138),
(
139),
(
311),
(
326),
(
338);




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

Суть проблемы: возникает сложные запросы для выборки товаров по атрибутам и их значениям, т.е. нужно найти flash с атрибутом пямять значение 2гб, цвет - беллый и весом 80г

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

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

  Ответить  

Сообщения:  [1-7] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования