@Akela_wolf
Extreme Programmer

Целесообразно ли хранить изображения как BLOB в БД?

Занимаюсь разработкой десктопного приложения. В программе будет работа со структурированной текстовой информацией и иллюстрациями. Текстовая информация прекрасно ляжет в локальную БД (планируется использовать SQLite, либо H2). А вот вопрос с хранением картинок пока остается открытым. Ожидается от нескольких десятков до нескольких тысяч изображений.

Одно из требований к приложению - возможность восстановления данных сторонними средствами. Таким образом, открытая БД позволяет подключиться к ней сторонним клиентом и вытащить оттуда любые данные (структура таблиц будет задокументирована). Также требуется возможность легко бэкапить данные и восстанавливать их из бэкапа.

Возникает соблазн сложить изображения в БД, точно также как и текст. Чтобы иметь все в одном файле, либо несколько файлов в каталоге (H2 умеет держать БД в ZIP-архиве, например), при необходимости БД можно легко сдампить и заархивировать. И точно также восстановиться из этого архива с дампом.

С другой стороны, везде встречаю рекомендацию не использовать БД для хранения файлов. Однако, как известно, "только ситхи всё возводят в абсолют".

Прошу совета - какие есть в данном случае подводные грабли в случае хранения изображений в БД? Оправдано ли это решение в данном случае на ваш взгляд?
  • Вопрос задан
  • 910 просмотров
Решения вопроса 2
ScriptKiddo
@ScriptKiddo
Несколько тысяч - можно и в БД
Вот что пишут про хранение небольших бинарников в базе SQLITE

SQLite читает и записывает небольшие BLOB-объекты (например, эскизы изображений) на 35 % быстрее¹, чем те же BLOB-объекты, которые можно читать или записывать в отдельные файлы на диске с помощью функций fread() или fwrite().

Кроме того, одна база данных SQLite, содержащая 10-килобайтные BLOB-объекты, использует примерно на 20 % меньше места на диске, чем хранение BLOB-объектов в отдельных файлах.

Разница в производительности возникает (мы полагаем), потому что при работе с базой данных SQLite системные вызовы open() и close() вызываются только один раз, тогда как open() и close() вызываются один раз для каждого BLOB-объекта при использовании BLOB-объектов, хранящихся в отдельные файлы. Похоже, что накладные расходы на вызовы open() и close() больше, чем накладные расходы на использование базы данных. Уменьшение размера связано с тем, что отдельные файлы дополняются до следующего кратного размера блока файловой системы, в то время как большие двоичные объекты более плотно упаковываются в базу данных SQLite.

https://www.sqlite.org/fasterthanfs.html
Ответ написан
@rPman
Десктопное приложение - хороший признак, неплохо описывает требования к хранилищу как однопользовательский, нет веб сервера (при его наличии и необходимость раздачи статичных файлов вопрос в выборе способа не стоит - однозначно файлами) и простота обслуживании.

Игроделы давно уже поняли что хранить миллион файлов (спрайты, модели и т.п.) удобнее в каком то упакованном виде, в файле, и большинство сильно не заморачиюватся и либо используют формат, предлагаемый фреймворком, либо берут готовый архиватор (zip например)

Достоинство выбора архивного формата - универсальность, наличие готового инструментария, возможность восстановления из коробки и главное, с архивом можно работать типовыми инструментами а не пилить свое.

Но и свой формат тоже где то оправдан, например уменьшение накладных расходов на хранение (например убрав имена файлов, оставив их идентификатор, можно сильно сократить размеры каталога/индекса). Совет, индекс хранить в конце файла, чтобы при изменении размеров при обновлении, не пришлось перекачивать весь файл, только потому что из-за одного изменившегося файла все остальные сдвинулись на несколько байт.

p.s. использовать sqlite для хранения файлов - плохая практика, даже если чтение будет быстрым (за счет того что sqlite это не сетевое подключение к базе данных, нет сериализации передаваемых данных и прочее), с записью все будет гораздо хуже. Попробуй гигабайтовой sqlite базой поманипулируй, тебе сильно не понравится (очень медленно), когда как обычный архиватор с опцией нулевого сжатия, работает на максимальной скорости работы диска.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
tsklab
@tsklab
Здесь отвечаю на вопросы.
Кроме прочего: если ваше приложение сможет показывать картинку без временного файла для неё — лучше BLOB.
Ответ написан
FanatPHP
@FanatPHP
Чебуратор тега РНР
Ну то есть логика этого вопроса в том, что по какой-то причине файл с БД забэкапить затруднительно, а вот картинки, которые лежат в этом файле - наоборот
Так же и "стороннее средство" в виде команды copy ну вообще ни с чем несовместимо, а создание/разворачивание "дампа" специфическими для БД средствыми доступно на каждом углу.
Не говоря уже про доступ к этим картинкам сторонними средствами.

Все-таки анекдот про Вовочку, "Где логика, где разум?" должен быть девизом этого сайта.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы