Tuesday, March 19, 2019

Учитесь программировать

На днях привалило мне «счастье» - 100 с гаком гигабайтов базы данных. Очень важных и очень интересных. Однако сразу всплыло несколько "но":
  1. База создана в Borland Interbase 7.5.
  2. Сами важные данные хранятся в виде BLOB-записей в графическом формате.
Сначала пришлось изрядно повозиться только для того, чтоб просто открыть базу, т.к. общедоступный Firebird этого формата не понимает. Потом выяснилось, что ни одна из популярных программ для работы с базами Interbase не умеет в пакетном режиме выуживать из оттуда BLOB-записи и сохранять их в виде файлов. Задача еще усложнялась тем, что мало выудить файл, надо еще его сохранить под правильным именем, которое хранится в отдельном столбце в таблице.
Делать нечего, пришлось экспортировать базу в формат SQLite. В принципе, на этом можно было бы и остановиться, SQLite вполне себе общеупотребимый и удобный формат, но опять проблемы:
  1. BLOB-записи из Interbase почему-то сконвертировались в HEX-строки SQLite (хотя тоже в формате BLOB). Т.е. из бинарного вида они превратились в ASCII: "04В458A4C1...". Т.е. напрямую с этими данными работать не получится — придется извлекать, конвертировать в бинарный вид и уже после этого открывать в графическом редакторе. Либо, как вариант, можно пройтись по базе и перекодировать данные.
  2. Сама идея хранить файлы в базе данных мне кажется сугубо порочной. Для файлов уже создана отличная база данных и называется она — файловая система.
  3. Программы, которые я подобрал для извлечения BLOB-записей из SQLite, отлично работают на маленьких базах, но на больших либо денег просят, либо падают от недостатка памяти при экспорте >1000-й строки (а всего там их около 80 тысяч), а часто и то и другое.
Помог скрипт sqlite-blob-dumper.py. Пришлось его немного модифицировать (о слава тем далеким годам, когда я занимался программированием), чтобы имена экспортируемых файлов брались из базы, а не генерировались на основе номера строки, названия базы и столбца с данными и все заработало. Причем довольно быстро и без проблем с памятью.
Скрипт уже выгрузил 80% базы, когда я понял, что могу сэкономить еще одну итерацию: ведь файлы сохранялись все в том же HEX-виде и для перекодирования в бинарный вид я собирался использовать отдельную программу xxd.exe — хорошую, но медленную под Windows. Тормознул скрипт, модифицировал, добавив в него функцию перекодирования. Теперь файлы сразу сохраняются в нужном бинарном виде — существенная экономия времени и дискового пространства.

P.S.: Для особо прозорливых, кто догадался, что это за база: извините, не моё — не дам.