Обновление товаров. XML -> SQL

jenia

Новичок
Обновление товаров. XML -> SQL

Есть задача - раз в сутки обновлять наличие и цену товара в электронном магазине. Для этого нужно распарсить xml, который забирается из 1С и обновить данные в БД. Товаров ~ 6000. Товары в БД и xml-файлы имеют артикул по которому сопоставляются. Получается мне для обновления данных нужно сделать около 6000 запросов к БД для того, чтобы узнать есть такой товар или нет и ещё 6000, чтобы обновить данные в таблице. Плюс к этому (при необходимости) добавить новые товары. Получается, что раз в сутки нужно сделать парсинг xml и 12000 запросо к БД.

Я всё правильно описал? Как сделать это я знаю (я регулярными выражениями разбираю xml и добавляю всё это в БД), просто меня смущает ресурсоёмкость таких действий. Более изящных решений нет?
 

AmdY

Пью пиво
Команда форума
зачем регулярки, тебе подойдёт xmlreader
для уменьшения колличества запросов можно делать так
для уменьшение колличества запросов можно
а) сразу выбрать одним запросом все артикулы находящихся там товаров, а затем проверять попадания товаров из xml
б) есть замечательный http://dev.mysql.com/doc/refman/5.0/en/replace.html
 

jenia

Новичок
AmdY, да, регулярки можно заменить на какой-то класс для разбора xml. Согласен.
Работа с двумя массивами на 6000 записей менее ресурсоёмка, чем 6000 запросов? Наверное да. Тут вы тоже правы.
Но всё таки 6000 запросов для обновления данных мне никак не обойти. Правильно?

Ещё один вопрос: я сомневаюсь, что скрипт справится с этим заданием за 30 секунд (ограничение на время выполнения скриптов). Или я не прав? Просто мне сразу писать скрипт, который будет перезапускатся через 30 секунд или возможно, что обработка займёт меньше времени?
 

AmdY

Пью пиво
Команда форума
xmlreader не обязательно должен создавать массив, он работает не с целым xml, а с его частями, тем самым можно обрабатывать даже очень большие xml файлы не грузя их полностью в память.
про 30 секунд http://www.php.net/manual/ru/function.set-time-limit.php
6000 запросов это не так много, многие популярные cms-ски используют по сотне запросов на одну страницу.

как вариант можно делать трансформацию xml -> sql dump, а уже дамп скармливать утилите mysqldump
 

slach

Новичок
jenia
1) уникальный ключ по Артикулу естественно
2) ну можешь еще попробовать генерить из XML cvs файл и делать в MySQL LOAD DATA IN FILE
см. http://dev.mysql.com/doc/refman/5.1/en/load-data.html

вообще запросов может быть гораздо меньше
алгоритм примерно такой
* вытаскиваем одним запросом все артикулы из MySQL в ассоциативный массив вида 'артикул' => ''
* создаем переменные $replaceSQL='REPLACE TABLE price(artikul,title) '; $insertSQL=' INSERT INTO price(artikul,title) '; $deleteSQL=' DELETE FROM price WHERE id IN (';
* пробегаемся с помощью XMLReader последовательно по XML'ю (кстати если парсится стандартная 1С выгрузка, то там теги русские могут и проблемы возникнуть с доступом ;),
как только получаем артикул. тогда проверяем,
он есть в массиве?
если есть, тогда $replaceSQL .= ' VALUES("'.$xmlreader->artikul.'","'.$xmlreader->title.'"),';
потом unset($artikuls[$xmlreader->artikul]);
если нет тогда $inserSQL .= ' VALUES("'.$xmlreader->artikul.'","'.$xmlreader->title.'"),';

после этого получаешь в памяти два больших запроса
выполняешь их
не забудь запятую удалить в конце
ну и кроме того
у тебя остается массив из тех ID которые
соответсвенно
$deleteSQL .= implode(',',$artikul);
получаешь массив в котором

можешь кстати дробить запросы по 100 единиц и счетчики ставить (обнуляя $insertSQL и $replaceSQL)

алгоритм ясен?
запросов будет меньше
работать должно достаточно шустро
 

Фанат

oncle terrible
Команда форума
скрипты, запускаемые из консоли, не имеют ограничения в 30 секунд. не надо этого детсадовского перезапуска
 

slach

Новичок
***** =) ты ничего не перепутал?? =)

с какого перепугу директива max_execution_time жестко прописанная в php.ini перестала распостранятся на CLI интерфейс???

вот тут, не могу найти сего чудесного упоминания
http://www.php.net/manual/en/function.set-time-limit.php

хотя вот тут
http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time

говорится о том, что дефолтное значение устанавливается в 0
т.е. если я правильно понимаю когда запускается php из CLI и в php.ini который он читает не стоит принудительно max_execution_time, тогда скрипт действительно "работает пока не сдохнет или не прибьют" =)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
slach
Код:
C:\WINDOWS>php -r echo(ini_get('max_execution_time'));
0
C:\WINDOWS>
В php.ini max_execution_time задан.
 

slach

Новичок
опс... и на старуху бывает проруха....
ок. буду знать скорее всего появилось в районе 5.1.х а я и не заметил.... =(((
 
Сверху