На новой работе большая часть времени уходит на работу с базой данных.
База большая, хаотичная и в целом — внушает ужас. Увы, отнюдь не объёмами, но скорее качеством данных.
Дабы вы поняли всю прелесть и пикантность ситуации, добавлю — база мало того, что неиндексированная, так ещё и с отсутствующим ключевым полем.
Хранится всё это Щастье в dbf. Разного рода вспомогательные базы, базочки, базюшечки и просто обновления — в том же dbf.
Поскольку с dbf я дружу слабо, а с MySQL — средне, было принято решение — "загнать эту ... базу в мускуль, а там видно будет".
Как это ни смешно, решение оказалось правильным. С другой стороны, есть подозрение, что правильным было бы любое решение, потому что один из принятых в этой конторе методов обработки информации заключался в "распечатать всё, а потом силами нескольких человек найти нужное в распечатках, а потом вручную вбить обратно".
Заканчивая лирическое отступление, расскажу — как я загоняю dbf-ки в MySQL и потом выковыриваю их обратно.
aptitude search навёл меня на утилиту dbf2mysql
Я не буду пересказывать здесь ман, вскользь отмечу только, что ключ "перевести имена полей в нижний регистр" работает, а вот "перевести значения полей в нижний/верхний регистр" — не работает.
У утилиты этой есть один, но существенный на мой взгляд недостаток.
Автор её и слыхом не слыхивал о существовании кодировок, отличных от latin1.
В результате имеем таблицу в кодировке latin1, набитую данными в кодировке CP866.
Но нас таким не напугаешь. Возможно кто-то применит секретное заклинание alter table, сменит тип данных с текстового на blob, выправит кодировку, а потом сменит тип данных обратно, но это не мой путь. Этих самых полей у меня — неисчислимое множество (ну вру. Исчислимое, что уж там. Но всё равно — много).
Выручает старый-добрый mysqldump с принудительным выставлением кодировки в latin1.
Обрабатываем полученный файл напильником iconv'ом, перегоняя из CP866 в юникод, меняем в нём кодировку с latin1 на utf8, drop-аем таблицу, загоняем дамп обратно в мускуль — et voila!
Дабы работать было удобнее, добавляю отдельное поле типа int, заполняю его автоинкрементом и индексирую по нему. Иначе — совсем грустно. Но это уже сугубо моя локальная специфика.
Самое интересное начинается, когда приходит время загнать данные из MySQL обратно в dbf. Вот тут уже — чистое шаманство.
Вышеупомянутая утилита dbf2mysql имеет и оборотную сторону mysql2dbf. И даже вроде как работает, но...
Но о кодировках, отличных от latin1 можно забыть.
Но настоящего джедая не напугать такими мелочами.
Берём, делаем выборку из MySQL, посредством INTO OUTFILE формируем csv, открываем готовую dbf-ку с нужной структурой редактором dbf от pssoft.ru (спасибо автору), удаляем все данные и импортируем туда данные из csv. Одно уточнение — данные в csv должны быть в CP1251, но это такие мелочи...
От счастливого финала нас отделяет только N-ное количество щелчков мышью. Каждое поле dbf-а нужно сопоставить полю csv-шки. Автоматизировать — никак. У меня таких полей — 70.
Клик-клик-клик...
Клик-клик-клик...
Клик-клик-клик...
ДААА! Экспорт в dbf и вожделенный файлик на диске, будь он неладен.
К чему всё это? К тому, что если кто знает способ лучше — я просто изнемогаю от желания его узнать. А пока тихо радуюсь, что результаты обработки в 90% случаев нужны не в dbf, а в xls, получить который из csv — дело пары минут.
Занавес.