X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

Открыть тему
Тема закрыта
> insert to mysql + удаление строки из файла
Licoric
Licoric
Topic Starter сообщение 21.1.2014, 13:33; Ответить: Licoric
Сообщение #1


У меня пока есть велосипед без колес.
Есть текстовый файл на 500 метров (примерно). В нем типовые строки.
Я беру и читаю файл построчно. Каждую строку заношу в мускульную базу.
Как мне теперь удалять прочитанную строку из файла?
Ограничение по тайм ауту - 30 секунд. За этот проход в базу попадает что-то около 150 тысяч записей. Я бы хотел бы сделать вилку на один проход в 100К записей и то, что в базе на ходу удалять. А скрипт запустить столько раз, сколько надо.
[PHP]$handle = fopen("apn3", "r+");
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$ins = explode("|", $buffer);
$query = "insert into apn
(`1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`) values
('".$ins[1]."', '".$ins[2]."', '".$ins[3]."', '".$ins[4]."', '".$ins[5]."', '".$ins[6]."', '".$ins[7]."', '".$ins[8]."', '".$ins[9]."')";
$result = mysql_query ($query, $db);
if (!$result)
{
echo "Недопустимый запрос: ".mysql_error()."<br>".$query;
die;
}else{
// тут нужно удалить только что добавленную в базу строку
}[/PHP]
Что-то типа такого получается.
Конкретного решения своей задачи не нашел. Вернее нашел, нор они портят немного исходный файл. Тестовый типовой файл на 30 строк дал выхлоп (фиг знает как) в over 900 000 строк.
А я просто добавил туда этот код: http://www.cyberforum.ru/post3305766.html
и убрал из кода запись в другой файл. В общем направьте на путь истинный.
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
alexdrob
alexdrob
сообщение 21.1.2014, 15:42; Ответить: alexdrob
Сообщение #2


Как мне теперь удалять прочитанную строку из файла?

перезаписать файл без строки.
Ограничение по тайм ауту - 30 секунд.

кто мешает его изменить?
зачем вообще такой скрипт запускать через вэб сервер?

по ссылке выше кривой метод, лучше уж тот что в следующем посте, без цикла.

почему бы не загрузить текст так http://dev.mysql.com/doc/refman/5.1/en/load-data.html
или хотя бы перегнать из текстового формата в sql и потом залить файл целиком, одним запросом.
можно даже нотепадом,
сначала экранировать все апострофы, то етсь просто заменить ' на \'
а потом заменить (тип регулярные выражения), в поиске что то типа ^(.*)$ а в замене \(\'$1\'\),
ну и первой строкой добавить insert into `table` (`field`) values
и в последней изменить , в конце на ;
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Licoric
Licoric
Topic Starter сообщение 21.1.2014, 17:06; Ответить: Licoric
Сообщение #3


[PHP]set_time_limit(0);[/PHP]
И нет проблем.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Witu
Witu
сообщение 21.1.2014, 18:02; Ответить: Witu
Сообщение #4


http://dev.mysql.com/doc/refman/5.0/en/loading-tables.html

самый оптимальный вариант
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
сообщение 22.1.2014, 23:38; Ответить: Arks
Сообщение #5


на первой итерации
1.1 открываете исходный файл на чтение (fopen, 'r')
1.2 читаете строку fgets
1.3 делаете запись в mysql,
1.4 где-то сложением с прочитанным strlen байт помечаете(например в apc) offset обработанных всего байт в файле
1.5 закрываете файл

на следующей итерации
2.1 открываете файл на чтение
2.2 делаете fseek на offset байт
2.3 повторить начиная с 1.2

одна итерация - цикл на 100к строк(повторять 1.2-1.4), после цикла делается п.1.5
п. 1.3-1.4 выполнять в транзакции. Сначала пишем в mysql, потом обновлем счетчик - только потом commit'им транзакцию в mysql

*если достигнут конец файла, закрыть файл(fclose) и сделать unlink. Да и упаси Бог с 500Мб файлами что-то читать целиком из файла или как-то накапливать прочитанные данные.

Возможна также реализация с двумя потоками, при которой можно сокращать первые n байт в файле на лету в обработке в ОП, но это требует уже 2 дескрипторов да и вообще вопрос сложный.

P.S. Для чего я все это пишу - потому что порой не стоит заталкивать в mysql 500Мб файлы пачкой, в т.ч. через load data. У mysql нету никаких оптимизаций на этот счет кроме стандартного свопа памяти. Т.е. в процессе заливки такого файла mysql дико затупит. Вставка по строчке же наоборот, будет за операцию производить большой оверхед но на сам mysql нагрузка будет минимальной по сравнению со вставкой такой штуки. Рекомендую вообще не заморачиваться, и тупо конвертировать любым быстрым конвертером файл в csv, затем подключать как готовую таблицу созданием .frm файла. При необходимости по cron где-нибудь ночью менять ALTER'ом движок и делать например MyISAM merge. Mysql сам все сделает, он умный! :)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Licoric
Licoric
Topic Starter сообщение 23.1.2014, 10:29; Ответить: Licoric
Сообщение #6


[PHP]
// время выполнения скрипта. 0 - без ограничений
set_time_limit(0);
$handle = fopen("apn", "r+");
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$ins = explode("|", $buffer);
$query = "insert into apn
(`1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`) values
('".addslashes(stripslashes($ins[1]))."',
'".addslashes(stripslashes($ins[2]))."',
'".addslashes(stripslashes($ins[3]))."',
'".addslashes(stripslashes($ins[4]))."',
'".addslashes(stripslashes($ins[5]))."',
'".addslashes(stripslashes($ins[6]))."',
'".addslashes(stripslashes($ins[7]))."',
'".addslashes(stripslashes($ins[8]))."',
'".addslashes(stripslashes($ins[9]))."')";
$result = mysql_query ($query, $db);
if (!$result)
{
echo "Недопустимый запрос: ".mysql_error()."<br>".$query;
die;
}else{
// счетчик действий
$numeric++;
}
}
fclose($handle);
echo "Всего добавлено записей: ".$numeric;
[/PHP]
Скрипт работает несколько минут. Зато никакого геморроя. Все добавилось как надо. Весь файл в 450+ метров.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Degradator
Degradator
сообщение 23.1.2014, 20:36; Ответить: Degradator
Сообщение #7


addslashes(stripslashes($ins[1])) для чего это?
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
сообщение 24.1.2014, 0:43; Ответить: Arks
Сообщение #8


Licoric, прошу внимательно перечитать мой пост и особенно обратить внимание на п.1.4 и изменить код соответствующим образом. Тогда проблем уже точно не будет.
"r+" не нужен. Нужен тут только "r" т.к. не увидел записи в файл. Сэкономьте один, совершенно лишний в рамках кода выше, поток.

Замечание модератора:
Эта тема была закрыта автоматически ввиду отсутствия активности в ней на протяжении 100+ дней.
Если Вы считаете ее актуальной и хотите оставить сообщение, то воспользуйтесь кнопкой
или обратитесь к любому из модераторов.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Открыть тему
Тема закрыта
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Открытая тема (нет новых ответов) Услуги по созданию и доработке скриптов PHP, MySQL, JavaScript, jQuery
Разработка сайтов и сервисов под-ключ
0 alexey 1246 24.11.2023, 14:46
автор: alexey
Открытая тема (нет новых ответов) Web программирование на С/С++/PHP/MySQL/SQL, высоконагруженные проекты
Есть наработки в области бирж трафика, топов, тизеров, видео cj-тубов
4 DFService 3356 8.4.2020, 18:02
автор: DFService
Открытая тема (нет новых ответов) Верстка, php + mysql, недорого
3 devprojectlab 2657 28.10.2019, 18:53
автор: Mukis
Открытая тема (нет новых ответов) Работа: Удаление фона с фотографий
0 upinseo 3210 18.9.2019, 12:01
автор: upinseo
Открытая тема (нет новых ответов) Удаление вирусов с сайтов, хостинга и серверов. Защита от взлома и устранение уязвимостей
0 vixan 2371 3.11.2018, 20:40
автор: vixan


 



RSS Текстовая версия Сейчас: 25.4.2024, 16:10
Дизайн