DBF в MySQL: Как я конвертировал ФИАС.

test

Добрый день, уважаемый читатель!

Вот, как всегда мне достаются весьма увлекательные задачи. В этот раз нужна была база улиц Челябинска и Казани. Те кто с подобным сталкиваются наверняка слышали о КЛАДР-е. Это такой себе список городов, улиц и т.д. Но он к 2011 году успел устареть морально и в плане разработки его забросили. К слову, тот же самый разработчик решил начать с чистого листа и в 2011г, и по текущее время разрабатывает базу ФИАС. База большая, архив 2ГБ, в распаковке около 10Гб. И вот я решил загнать всю эту базу в MySQL. Заодно скилы подтянуть. В дополнение ко всему единственный нормальный конвертер dbf2mysql для линукса поддерживает кодировку только latin1.

Выкладывают эту базу на сайте Федеральной Налоговой Службы(ФНС)
Выкладывают ее там в формате DBF и XML. Мы будем работать с DBF.

Итого, имеем платформу Debian GNU\Linux на 8-ядерном сервере, 12Гб ОЗУ и базу данных разбитую файликами на 10Гб в формате DBF.

Сам скрипт конвертации вышел таким вот:
indir - директория в которой лежат файлы DBF и DBT. Скрипт по ней проходит, по всем файлам, после обработки удаляет. Если не нужно удаление, просто удалите в строке rm /tmp/$table.out.sql&rm /tmp/$table.outtmp.sql&rm $file

#!/bin/bash
indir="../"
dblogin="root"
dbpass="yourpassword"
db="fias"
host="localhost"
postfix=".DBF"
prefix="./"
cd $indir
for file in `find ./ -type f -name "*$postfix"`
do
    table_tmp=${file%$postfix}
    table_tmp=${table_tmp#$prefix}
            table=${table_tmp,,}
    echo "WORK WITH :$table"
        dbf2mysql -vvv -d $db -t $table -c -h $host -P $dbpass -U $dblogin $file
    mysqldump -u$dblogin -p$dbpass --default-character-set=latin1 $db $table>/tmp/$table.sql
            iconv -f cp866 -t utf-8 /tmp/$table.sql>/tmp/$table.outtmp.sql
    more /tmp/$table.outtmp.sql|sed 's/latin1/utf8/'>/tmp/$table.out.sql
            mysql -u$dblogin -p$dbpass -T --show-warning -e "delete from $table" $db
    mysql -u$dblogin -p$dbpass -T --show-warning $db</tmp/$table.out.sql
        #   break
rm /tmp/$table.out.sql&rm /tmp/$table.outtmp.sql&rm $file
done


Делаем его исполняемым:
chmod +x dbf2mysql.sh


Немного объяснений. Скрипт смотрит все файлики в папке indir с расширением postfix и уже идя по циклу:
  1. Дергает название файла. Удаляет расширение. Удаляет prefix, в нашем случае это часть пути "./".
  2. Конвертирует файл заливая в MySQL, в таблицу с названием из п.1
  3. Делает дамп таблицы в папку /tmp с названием таблицы и расширением .sql
  4. Меняет кодировку в файле с cp866 в utf-8
  5. Меняет кодировку в дамп-файле таблицы
  6. Удаляет такую таблицу если она уже есть, а она есть, это следует из п.2
  7. Загоняет дамп в таблицу с именем из п.1., но уже в нужной кодировке.
  8. Удаляет временные файлы


Ну вот собственно и вся казалось бы конвертация. Но естественно скрипт работает в 1 поток всего, и достаточно медленно. Если у вас маленькая база данных, то думаю дальше можете не читать.

Чтобы как-то все это чудо ускорить и разделить, мы создадим и примонтируем раздел в памяти ОЗУ. Своп я сразу отключил, чтобы видеть ограничения по памяти.
swapoff -a

mkdir /mnt/ramdisk1
mkdir /mnt/ramdisk2
mkdir /mnt/ramdisk3
mkdir /mnt/ramdisk4

mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk1
mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk2
mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk3
mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk4


Дальше я скопировал файл конвертации, он у меня лежит в поддиректории converter в каждый из этих временных разделов. Выше уровнем скопировал по несколько файлов. После чего выполнил команды
/mnt/ramdisk1/converter/dbf2mysq.sh&
/mnt/ramdisk2/converter/dbf2mysq.sh&
/mnt/ramdisk3/converter/dbf2mysq.sh&
/mnt/ramdisk4/converter/dbf2mysq.sh&


Либо, если хотите наблюдать за процессом, как я в screen, в каждом собственном окне запустил отдельно каждую команду:
/mnt/ramdisk1/converter/dbf2mysq.sh

Но это уже дело вкуса.

Все, файлики работают в фоне и каждый гребет данные из своей папки. Естественно конвертировать ФИАС 4Гб ОЗУ не хватит, но тут я решил не рисковать и просто потом закинуть еще файлы и запустить скрипты повторно.
Категория: 
Share/Save

Делитесь с друзьями в социальных сетях! Оставляйте комментарии!

Share/Save

Это Вам так же может быть интересно!