Сравнение бд на разных хостингах

Статус
Закрыто для дальнейших ответов.

DnAp

self::setDebugMode(true);
Регистрация
30.04.2005
Сообщения
490
Вобщем описание задачи:
Есть 2 хостинга с идеентичной структурой базы и ~3000 записей в каждой...
Задача: Сравнить базы по полю main_url и вернуть ид тех записей которых нету в второй базе...

Предположительная реализация:
Кладем на один сервер код который отдает нам ряды(в том коде ошибок нету)
и пытаемся делать так:
Код:
<?// сравнение баз
function write_log($text) // записываем лог(чтоб отслеживать ход событий)
{
	$f=fopen("log.log","a");
	fwrite($f,"\n".date("r")."\n".$text."\n");
	fclose($f);
}
set_time_limit(0); // чтоб не сваливался через 30 сек
	write_log("Начало сравнения");

	$bd1=mysql_connect('localhost','root');
	mysql_select_db('test',$bd1); // подключились к локальной базе
	
	$table_name='linkcontrol_all';
	
	//... более хитрый код
	$fp=fopen("http://site.ru/link_export.php?count",'r'); // получаем сколько всего рядов в базе
	$count=fread($fp,1000);
	fclose($fp);

	// зацикливаем и получаем по 60 тк unserialize всю базу не вытягивает за один раз!
	$rows=array();
	for($i=0;$i<ceil($count/60);$i++)
	{
		if($fp=fopen("http://site.ru/link_export.php?p=".$i,'r'))
		{
			$array='';
			// читаем по кусочкам из-за особеностией функции fread которая не может прочитать больше 4380 символов.
			while (!feof($fp)) {
				$array.=fread($fp,4380);
			}
			$tmp_rows=unserialize($array);
			// мержим
			foreach ($tmp_rows as $row) {
				$rows[]=$row;
			}
			unset($array,$tmp_rows); // следим за чистотой;)
		}
	}
	// первая часть извращения кончилась
	
	// выкидываем все лишнее
	$url_arr[]=array();
	foreach ($rows as $row) {
		$url_arr[]=$row['url_main'];
	}
	unset($rows); // экономим все еще;)

	$id_arr=array();
	$result=mysql_query("SELECT id,url_main FROM ".$table_name,$bd1); // получаем все записи и ид.
	write_log(mysql_num_rows($result)." - ".count($url_arr)); // надо порадоать что все ок.
	while ($assoc = mysql_fetch_assoc($result)) {
		if(array_search($assoc['url_main'],$url_arr)===false) // ищем все значения
		{
			write_log("Нашел различие");
			$id_arr[]=$assoc['id'];
		}
	}
	
	$rows=array();
	$export_arr=array();
	// получаем все записи для экспорта
	foreach ($id_arr as $current_id) {
		$result=mysql_query("SELECT * FROM ".$table_name." WHERE id='".$current_id."'",$bd1);
		$rows[]=mysql_fetch_assoc($result);
	}
	
	$fp=fopen("compare.bd","w");
	fwrite($fp,serialize($rows)); // последний штрих
	fclose($fp);
	// Порадумся чуть чуть все:))
	write_log("Сравнение базы зкончено");
?>

Вобщем с маленькой базой справляеться на ура, но как выходит несколько тысяч записей скрипт уверено говорит что базы идеентичны, хотя это точно нетак!

Может я уставший и не соображаю но непонимаю нифига почему не пашет?!?

ЗЫ
Всетаки пхп до солидного языка програмирования далеко, 2 извращения пришлось писать:((
 

the_naked

New Member
Регистрация
06.04.2006
Сообщения
6
Предлагаю следующий вариант: выбираем из базы все main_url (ну и еще что нужно для идентификации поля потом), записываем в один файл делая сортировку по какому-нибудь принципу (1.txt), то же делаем со второй таблицей (2.txt),потом сравниваем два файла (это уже легче - памяти не требует много, а из-за того, что все отсортировали достаточно проверять строки с одинаковыми номерами - если не совпало, то несовпашее заносим в другой файл, далее в одном указатель не смещаем, а в другом смещаем - сравнение выполняется за n шагов)... Вот, попробуй так.
P.S.: а в PostgreSql в пхп можно создавать сразу два подключения, что иногда реально улучшает жизнь...;)
 

DnAp

self::setDebugMode(true);
Регистрация
30.04.2005
Сообщения
490
Спасибо, это мысль...
ЗЫ
у серверов доступ к базе разрешон только от локалхоста:(
 

medwoodu

Злобный модер
Регистрация
22.12.2005
Сообщения
1 418
Один из вариантов сравнения оочень больших бд:
1) Необходимы: файл на одном из хостов по номеру возвращающий N записей из бд. файл на втором хосте, делающий такой же вызов устанавливающий сокеты с первым хостом с этим файлом и обрабатывающий результаты.

2)Организуется процесс(JS) поочередного вызова файла с параметром типа index.php?sql_id=0 (10,20) - необходимо, если время работы скрипта на хосте маленькое.

С помощью такого приема можно обрабатывать очень большие массивы данных.
 

deMone

Злой страшный дядька
Регистрация
30.01.2006
Сообщения
937
А у меня спокойно работает с большими массивами данных. Есть скрипт, который вставляет одним INSERT-запросом до 40000 записей, а потом их же считывает (ну, нужно там)...

P.S.: а в PostgreSql в пхп можно создавать сразу два подключения, что иногда реально улучшает жизнь...;)
MySQL это тоже умеет. Причём соединений можно сделать не два, а сколько угодно.
 

medwoodu

Злобный модер
Регистрация
22.12.2005
Сообщения
1 418
deMone, скорее всего там стоит ограничение на время выполнения скрипта, просто половина проги зарубается.
 

deMone

Злой страшный дядька
Регистрация
30.01.2006
Сообщения
937
set_time_limit();
 

DnAp

self::setDebugMode(true);
Регистрация
30.04.2005
Сообщения
490
Вобщем переписал по совету The_naked, все заработало...
set_time_limit(0); у меня был...
Но как показала практика 2 из 3-ех хоситнгов в принудительном порядке выкидывают скрипт через 3 минуты!
 

deMone

Злой страшный дядька
Регистрация
30.01.2006
Сообщения
937
Правильно, на многих хостингах отключена возможность совсем отменить ограничения по времени. Но можно сделать эти ограничения очень большими... Как насчёт set_time_limit (600)?

Впрочем, в совете уже, видимо, нет необходимости...
 

DnAp

self::setDebugMode(true);
Регистрация
30.04.2005
Сообщения
490
Бльше 3 минут не поставить, пробовал:(
В действительно нет необходимости...
Так что
this->close();
 

deMone

Злой страшный дядька
Регистрация
30.01.2006
Сообщения
937
Я бы сказал die(0);
 
Статус
Закрыто для дальнейших ответов.
Верх Низ