 |
 |
Форум сетевых администраторов » Программирование » PHP » Сравнение двух бааальших массивов
| Автор |
| Тема |
 |
|
 |
|
|
|
Участник
|
Сравнение двух бааальших массивов |
[сооб. #76486]
19-05-2005 09:17 |
|
Участник


Зарегистрирован: Dec 2003
Место проживания: Хабаровск
Публикаций: 57
Статус: ![[wish]master в оф-лайне](images/offline.gif) |
Проблема! Нужен хэлп!
Есть два здорооовых массива. Один из файла. Другой из базы данных. Структура одинакова.
Нужно их сравнить и выбрать из того, что из файла, строки, отсутствующие в базе данных.
Сравнение по одной колонке - code. Вариант решения прилагаю. НЕ Ð_АБОТАЕТ!
Проблема где-то в цикле: while($read = mysql_fetch_array($query))
Понять не могу в чем дело! Первые n срок сравнивает нормально, потом БОÐ_ОДА!
Суть проблемы понять не могу... хееелпь миии плиииз...
Может есть какие-нибудь быстрые функции в mysql, которыми можно сделать сравнение с массивом в запросе, не делая выборки из базы?
PHP:
$total=0;
$ttt=microtime();
$ttt=((double)strstr($ttt, ' ')+(double)substr($ttt,0,strpos($ttt,' ')));
$abort = ignore_user_abort(1);
@set_time_limit(600);
//////////////////////////////////////////////////////////
// запихиваем содержимое файла в массив
$pricefile = file("data/prices/computer.csv");
// получаем таблицу из базы
$query = mysql_query("SELECT * FROM ss_prices");
$news = array();
$count = 0;
// смотрим массив из файла
foreach($pricefile as $string) {
// разбиваем строки на нужные кусочки
list($group,$cat,$subcat,$brand,$code,$name,$partn um,$price,$warehouse) = explode(";",$string);
if($code != "" AND is_numeric($code)) {
$count++;
// обновлять
$new = 1;
// смотрим данные из базы
while($read = mysql_fetch_array($query)) {
// если находим совпадение, устанавливаем флаг не обновлять и прерываем цикл
if($read['ss_code'] == $code) {
$new = 0; //echo $read['ss_code']." <font color=red>=</font> ".$code."<br>";
break;
}
}
// обновлять, так обновлять - создаем массив обновления
if($new == 1) {
$news[] = $code." : ".$name;
}
}
}
//////////////////////////////////////////////////////////
$ddd=microtime();
$ddd=((double)strstr($ddd, ' ')+(double)substr($ddd,0,strpos($ddd,' ')));
echo ("<br>Ð_азмер обработанного файла: ".(number_format((round ((filesize("data/prices/computer.csv"))/1024)) , 0, ".",".")))." Кб<br>";
echo ("Обработано строк из файла: ".count($pricefile)."<br>");
echo ("Время обработки: ".(number_format(($ddd-$ttt),3))." секунд<p>");
echo ("Всего найдено позиций по прайсу: ".$count."<br>");
echo ("<font color=red>Найдено новых позиций: ".count($news)."</font><br>");
Структура базы такая:
PHP:
mysql_query("CREATE TABLE ss_prices (
ss_id int(11) unsigned NOT NULL auto_increment,
ss_code int(11) unsigned NOT NULL DEFAULT '0',
ss_name text NOT NULL,
ss_partnum int(11) unsigned NOT NULL DEFAULT '0',
ss_price int(11) unsigned NOT NULL DEFAULT '0',
ss_warehouse int(11) unsigned NOT NULL DEFAULT '0',
ss_group varchar(255) NOT NULL DEFAULT '',
ss_cat varchar(255) NOT NULL DEFAULT '',
ss_subcat varchar(255) NOT NULL DEFAULT '',
ss_brand varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (ss_id))");
__________________
Однажды, только ты поверь,
Маятник качнется в правильную сторону...
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
19-05-2005 09:17 |
|
|
Участник
|
| > "Может есть какие-нибудь быстрые функции... |
[сооб. #76487]
19-05-2005 09:28 |
|
Участник

Зарегистрирован: Apr 2005
Место проживания:
Публикаций: 35
Статус:  |
> "Может есть какие-нибудь быстрые функции в mysql, которыми можно сделать сравнение с массивом в запросе, не делая выборки из базы?"
Насколько я знаю, нет.
Попробуй в php включить warnings и notices
> "Первые n срок сравнивает нормально, потом БОÐ_ОДА!"
Что значит "борода"? Массивы одинаковые, а пишет, что разные? Или из цикла выходит? Или вываливается с ошибкой MySQL? Или чего вообще? И чему равно n ?
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
19-05-2005 09:28 |
|
|
Участник+
|
| Если массив огромный имхо, слить данные из... |
[сооб. #76538]
22-05-2005 19:38 |
|
Участник+


Зарегистрирован: Dec 2001
Место проживания: Россия Е-бург
Публикаций: 322
Статус:  |
Если массив огромный имхо, слить данные из mysql в файл, а там дальше сравнивать два файла.
__________________
http://faq.pp.ru/read_mee/
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
22-05-2005 19:38 |
|
|
STFW
|
RTFM http://www.php.net/manual/ru/function.array-diff.php
[quote]
array_diff
(PHP... |
[сооб. #76543]
23-05-2005 08:33 |
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
RTFM http://www.php.net/manual/ru/function.array-diff.php
quote:
array_diff
(PHP 4 >= 4.0.1, PHP 5)
array_diff -- Вычислить расхождение в массивах
Описание
array array_diff ( array array1, array array2 [, array ...] )
Функция array_diff() возвращает массив, состоящий из значений массива массив_1, которые отсутствуют в любом другом массиве, перечисленном в последующих аргументах. Обратите внимание, что ключи массивов сохраняются.
Пример 1. Пример использования array_diff()
$array1 = array ("a" => "green", "red", "blue", "red");
$array2 = array ("b" => "green", "yellow", "red");
$result = array_diff ($array1, $array2);
В результате выполнения этой программы переменная $result будет содержать array ("blue");. Повторения одного и того же значения в $array1 обрабатываются как одно значение.
Замечание: Два элемента считаются одинаковыми если и только если (string) $elem1 === (string) $elem2. Другими словами, когда их строковое представление идентично.
Замечание: Обратите внимание, что эта функция обрабатывает только одно измерение n-размерного массива. Естественно, вы можете обрабатывать и более глубокие уровни вложенности, например, используя array_diff($array1[0], $array2[0]);.
остальное (array_diff*, array_udiff*): http://www.php.net/manual/ru/ref.array.php
сначала можно выбрать отличающиеся строки (row) целиком, а потом выяснить какое поле изменилось в каждой строке...
__________________
FAQ OFF
Сообщение было отредактировано SCHIZO 23-05-2005 в 08:37
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
23-05-2005 08:33 |
|
|
Участник+
|
| а оно у вас так и задумано по алгоритму; очень... |
[сооб. #76570]
24-05-2005 17:57 |
|
Участник+


Зарегистрирован: Apr 2002
Место проживания: Россия, Пятигорск
Публикаций: 69
Статус:  |
а оно у вас так и задумано по алгоритму; очень маловероятно, что оно дойдет в цикле до второго по счету элемента массива pricefile... 
я бы построил следующим образом:
1) текстовую базу - в массив
2) выборка из базы одним запросом
3) while.. цикл - по записям базы!!
4) поиск в_массиве!! нужной строки: array_search ()
5) обработка (insert или_что_там_нужно)
и типа все...
__________________
Всякое решение порождает новые проблемы...
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
24-05-2005 17:57 |
|
|
Участник
|
| sVs, доходит и до двадцать второго. А array_search()... |
[сооб. #76576]
24-05-2005 22:50 |
|
Участник


Зарегистрирован: Dec 2003
Место проживания: Хабаровск
Публикаций: 57
Статус: ![[wish]master в оф-лайне](images/offline.gif) |
sVs, доходит и до двадцать второго. А array_search() я пробовал - время выполнения 33 секунды для 14000 строк в одном массиве и 11000 в другом - это не серьезно. Массивы со временем вырастут.
SCHIZO, на днях запробую неизвестную доселе функцию array_diff()... Спасибо! По результату отпишу...
__________________
Однажды, только ты поверь,
Маятник качнется в правильную сторону...
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
24-05-2005 22:50 |
|
|


STFW
|
| Если массивы вырастут, обрабатывай по лимиту,... |
[сооб. #76582]
25-05-2005 08:36 |
|
STFW


Зарегистрирован: Jul 2002
Место проживания: Кольский п-ов
Публикаций: 305
Статус:  |
Если массивы вырастут, обрабатывай по лимиту, скажем не более 10000 строк за раз..
P.S.
Отрабатывать функцию лучше не небольшых массивах со всеми возможными вариантами действий.
__________________
FAQ OFF
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
25-05-2005 08:36 |
|
|
Участник+
|
| не в быстродействии и не в кол-ве данных тут... |
[сооб. #76595]
26-05-2005 00:15 |
|
Участник+


Зарегистрирован: Apr 2002
Место проживания: Россия, Пятигорск
Публикаций: 69
Статус:  |
не в быстродействии и не в кол-ве данных тут дело вовсе.. а в изначально кривом алгоритме...
мотивирую:
Ð_ассмотрим случай - в текстовом файле строк БОЛЬШЕ (110шт), чем в базе (100шт) и все новые строки (10шт) - в конце текстовика.
В результате запроса-выборки (перед циклом foreach) вы получаете указатель на результат, ряд срок (100шт) которого - заведомо меньше, чем кол-во строк в массиве(110шт), по которому организуете цикл foreach.
Далее внутри цикла (по 110 строкам массива) организуете цикл while (100 строк), где перебираете результат sql запроса. Приехали...
цикл while у вас не может быть выполнен В ПÐ_ИНЦИПЕ более 100 раз, т.е. сделав 100 раз mysql_fetch_array, далее 10 оставшихся массива и сравнивать не с чем будет (указатель не перейдет опять на первую запись, это не кольцо Мебиуса).
В случае, если в текстовом файле строк меньше (50шт), чем в базе (60шт), например часть тех, что в базе и часть новых - все еще веселее:
-внешний цикл foreach (50 проходов)
-внутренний цикл while (будет выполнен не более 60 раз ВСЕГО), а нужно сравнить каждый_с_каждым..
Короче мораль - или перенесите mysql_query внутрь цикла foreach (неоптимально), либо воспользуйтесь моим предыдушим советом
PS> функции array_search и array_diff базируются на одних и тех же принципах поиска/сравнения данных и что юзать - дело вкуса, только во втором случае вам надо загрузить всю базу во второй массив 
> время выполнения 33 секунды для 14000 строк...
Re: спорим, можно сделать алгоритм, который массив из 1-го элемента будет полгода перебирать? 
__________________
Всякое решение порождает новые проблемы...
Сообщить модератору об этом сообщении | Предупреждение | IP: определен
|
26-05-2005 00:15 |
|
|
|
Формат времени GMT. Текущее время 22:58.
|
Правила форума:
Вы не можете создавать новые темы.
Вы не можете отвечать на существующие темы.
Вы не можете прикреплять файлы.
Вы не можете редактировать свои сообщения. |
HTML теги выкл.
Спец. код вкл.
Смайлики вкл.
[IMG] тег выкл.
|
|
|
|
| |
Page generated in 0.77959394 seconds (99.36% PHP - 0.64% MySQL) with 26 queries.
|
 |