Еще одним из интересных заданий было обработать две таблицы: товары и цены. Суть заключалась в том, что надо было составить прайс из 10к товаров, но реально товаров существовало 100к, а в таблице цен на каждый товар приходилось по 4 разные цены для каждой группы покупателей (вип, опт, розница, лучший друг и тп). Такоже небольшим нюансм было, что товары имели разный статус, пусть он для нас будет, как «в продаже/нет в наличии».
Начнем с того, какие у нас таблицы:
CREATE TABLE `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(200) NOT NULL, `status` tinyint(1) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `prices` ( `product_id` int(11) NOT NULL, `type` smallint(6) NOT NULL, `price` float(10,2) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
В pruducts у нас 100к записей, а в prices — 400к (100к товаров по 4 цены на каждый).
Для примера как там что выглядит два результата запроса:
MariaDB [test]> SELECT * FROM products LIMIT 8; +----+----------+--------+ | id | name | status | +----+----------+--------+ | 1 | 0519f01d | 1 | | 2 | 5e29798b | 0 | | 3 | a6284069 | 1 | | 4 | 91c2fa3e | 1 | | 5 | d928535b | 1 | | 6 | b8367e94 | 0 | | 7 | 2fca5bd8 | 1 | | 8 | b1df04c1 | 0 | +----+----------+--------+ 8 rows in set (0.00 sec)
MariaDB [test]> SELECT * FROM prices LIMIT 8; +------------+------+--------+ | product_id | type | price | +------------+------+--------+ | 1 | 1 | 63.00 | | 1 | 2 | 56.70 | | 1 | 3 | 50.40 | | 1 | 4 | 44.10 | | 2 | 1 | 474.00 | | 2 | 2 | 426.60 | | 2 | 3 | 379.20 | | 2 | 4 | 331.80 | +------------+------+--------+ 8 rows in set (0.00 sec)
Теперь по порядку, что у нас где…
products.id — уникальный ID товара
products.name — название товара
products.status — в продаже/нет в наличии
prices.product_id — ID товара
prices.type — тип цены (опт, розница, вип и тп)
prices.price — цена в неких единицах измерения
Теперь добавлю скрипт для обработки этих данных. Старался писать комментарии, чтобы было понятно, но вдруг чего не стесняйтесь писать в комментариях на страничке.
<?php // Config $cfg['host'] = "localhost"; $cfg['name'] = "test"; $cfg['user'] = ""; $cfg['pass'] = ""; $cfg['limit'] = 10000; // Connect to DB mysql_connect($cfg['host'], $cfg['user'], $cfg['pass']) or die ("Не могу создать соединение"); mysql_select_db($cfg['name']) or die (mysql_error()); mysql_query("set names 'utf8'"); $sql = "SELECT p.name, pr.type, pr.price FROM prices pr, products p WHERE pr.product_id = p.id AND p.status = 1"; $result = mysql_query($sql); $price = array(); $y = 0; while(($product = mysql_fetch_assoc($result)) && ($y <= $cfg['limit'])) { // Если такого товара нет в массиве увеличиваем счетчик товаров if(!$exist = array_key_exists($product['name'], $price)) $y++; // Убиваем обработку лишнего товара if($y > $cfg['limit']) break; $type = 'type' . $product['type']; // Формируем массив с именем в роли ключа и массивом цен в роли значения // Проверяем есть ли товар в массиве, если да, то просто дополняем его массив цен, // если его нет - создаем if($exist) { $price[$product['name']] = array_merge($price[$product['name']], array($type => $product['price'])); } else { $price[$product['name']] = array($type => $product['price']); } }
Теперь у нас есть один большой массив с подмассивами товаров и их цен.
Array ( [0519f01d] => Array ( [type1] => 63.00 [type2] => 56.70 [type3] => 50.40 [type4] => 44.10 ) [a6284069] => Array ( [type1] => 465.00 [type2] => 418.50 [type3] => 372.00 [type4] => 325.50 ) ... )
Разбирать такой массив не сложно, вот пример:
// Разбираем массив создавая читабельный прайс (как пример) $prices = "# | Product | Price 1 | Price 2 | Price 3 | Price 4\n"; $x=1; // Простая считалка строк для наглядности foreach($price as $name => $prices_array) { $prices .= "$x | $name | {$prices_array['type1']} | {$prices_array['type2']} | {$prices_array['type3']} | {$prices_array['type4']}\n"; $x++; } // Вывод таблички print_r("<pre>$prices</pre>");
Вот такую страницу мы получим в конечном счете (я ее немного обрежу, как никак 10к строк писать нет смысла):
# | Product | Price 1 | Price 2 | Price 3 | Price 4 1 | 0519f01d | 63.00 | 56.70 | 50.40 | 44.10 2 | a6284069 | 465.00 | 418.50 | 372.00 | 325.50 3 | 91c2fa3e | 320.00 | 288.00 | 256.00 | 224.00 ..... 9998 | 0b0158a3 | 267.00 | 240.30 | 213.60 | 186.90 9999 | f529c8b4 | 788.00 | 709.20 | 630.40 | 551.60 10000 | d70b69b3 | 807.00 | 726.30 | 645.60 | 564.90
У меня эта страница генерировалась в среднем за 1,5 секунды. Кто не верит может заюзать в скрипте microtime() и лично убедится в этом.
30 октября, 2013 at 4:16 пп
Если кол-во цен фиксировано, то нужно было создать 4 колонки вместо 4-х строк.
id | product_id | price1 | price2 | price3 | price4
30 октября, 2013 at 5:23 пп
Тогда было бы всё намного проще) Такое задание дали, что поделаешь.