28 февраля 2006

Быстрая загрузка CSV-файла в базу данных

Как известно, для работы с CSV-Файлами PHP предоставляет функции fgetcsv и fputcsv. Поскольку эти функции обрабатывают файл построчно, то загрузка данных в базу данных происходит очень медленно: я так ни разу и не дождался, когда же обработается тестовый файл 40 метров длиной.

Опрос показал, что есть специальные средства, позволяющие загрузить CSV в базу очень быстро - речь шла о софтине bcp из комплекта MS SQL. Но тулза эта виндовая, а мне требовалось решение на кросс-платформе.

Так я обнаружл в MySQL'е наличие мега-структуры LOAD DATA IN FILE. Работает ну очень быстро: мой преславутый файл в 40 метров загружается за 16 секунд. В этом SQL-запросе есть всё, что надо для работы с CSV: указание символов для экранирования и отквочивания, пропуск первых N строк (заголовок), итд.

Кому лень ковырять мануал, милости прошу поюзать специально мной написанный для этой цели PHP-класс.

13 комментов:

Yuri комментирует...

Pochemuto, ssylka na phpclasses.org daet obschiy spisok classov.Probyval iskat' po vachey familii - ne nashel. Poprav'te pozhaluista ssylku.

A4 комментирует...

Да, есть такое дело :[

Это потому что админ сайта ещё не заапрувил мой класс.

Временно поменяю ссылку, пока админ не сделает своё чёрное дело, на свой хостинг, качайте.

Yuri комментирует...

Ura, rabotaet. Spasibo. Skazhite a kak mozhno avtomatizirovat' process zakachki csv-filov v bazu, chtoby ono samo zariazhalos' kak tolko noviy file poiavliaetsa v papke na servere ?

a4 комментирует...

Не за что.
Я вижу только один подход: проверять наличие новых файлов в папке, после чего запускать их загрузку в базу.

На счёт регулярных запусков - тут лучше использовать cron

Если что не понятно - спрашивай, я это уже делал.

A4 комментирует...

Админ заапрувил мой класс, теперь он доступен для всех желающих.

yuri комментирует...

Александр, эдраствуй. Можешь мне выслать файл-пример 3робота-крон3 закачи csv в базу данных, я гляну как ты его сделал?

A4 комментирует...

Привет!

Робота делать не надо - крон стоит на хостинге. Посмотри по ссылке выше (на php.spb.ru): чтобы всё заработало, тебе нужно просто сделать текстовый файл, в котором указать периодичнось и команду.

Команду лучше писать "wget URL" - таким образом ты просишь аналог линуксового FlashGet'а скачать текст с определённого урла. Пусть это будет твой урл, запускающий что-там-тебе-нужно-делать-регулярно.

Я понятно объяснил? :]

GArt комментирует...

Спасибо за скрипт. как говорится идея витала в воздухе, но ты всех опередил :-). Прада неплохо было бы предусмотреть не просто заливку, но и перезапись (обновление).

A4 комментирует...

Что ты имеешь ввиду: UPDATE вместо INSERT?

gart комментирует...

Не совсем в описанной тобой струтуре присутствует один момент
LOAD DATA INFILE 'file_name.csv' [REPLACE | IGNORE]
^^^^^^^^^^^^^^^^^^^^
INTO TABLE .....
он то и определяет будет ли обновлятся таблица или дозаписываться, правда работает это только в том случае если есть ключевые поля.

A4 комментирует...

Да, я думаю постепенно реализовать в классе все возможности, предоставляемые этим запросом, там их много. Не всё сразу :]

gart комментирует...

Еще маленький вопрос. По умолчанию создаются текстовые поля. Нельзя ли исправить этот момент? Т.е. если в CSV файле число, то что бы числовое поле и создавало. Я понимаю что в файле все выглядит строкой, но все-же...

A4 комментирует...

Об этом я тоже думал, можно сделать.

Отправить комментарий