Хранение изображений в БД - да или нет?

Поэтому я использую приложение, которое в большой степени хранит изображения в БД. Что вы думаете об этом? Я больше похож на то, чтобы хранить расположение в файловой системе, чем хранить его непосредственно в БД.

Как вы думаете, плюсы / минусы?

56 ответов

Я отвечаю за некоторые приложения, которые управляют многими ТБ изображений. Мы обнаружили, что лучше всего хранить пути к файлам в базе данных.

Есть пара вопросов:

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

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

  • Вы храните изображения, которые динамически изменяются, например, счета-фактуры, и вы хотите получить счет-фактуру, как это было 1 января 2007 года?
  • Правительство хочет, чтобы вы сохранили 6 лет истории
  • Изображения, хранящиеся в базе данных, не требуют другой стратегии резервного копирования. Изображения хранятся в файловой системе
  • Легче контролировать доступ к изображениям, если они находятся в базе данных. Свободные администраторы могут получить доступ к любой папке на диске. Требуется действительно решительный администратор, чтобы подглядывать в базу данных, чтобы извлечь изображения

С другой стороны, есть проблемы, связанные

  • Требовать дополнительный код для извлечения и потоковой передачи изображений
  • Задержка может быть медленнее, чем прямой доступ к файлам
  • Более тяжелая нагрузка на сервер базы данных

Файловое хранилище. Инженеры Facebook здорово поговорили об этом. Один из них - узнать практический предел количества файлов в каталоге.

Игла в стоге сена: эффективное хранение миллиардов фотографий

Это может показаться чем-то большим, но если вы используете (или планируете использовать) SQL Server 2008, я бы посоветовал взглянуть на новый тип данных FileStream.

FileStream решает большинство проблем, связанных с хранением файлов в БД:

  1. Капли на самом деле хранятся в виде файлов в папке.
  2. К BLOB-объектам можно получить доступ через соединение с базой данных или через файловую систему.
  3. Резервные копии интегрированы.
  4. Миграция "просто работает".

Однако "прозрачное шифрование данных" в SQL не шифрует объекты FileStream, поэтому, если это важно, вам лучше просто хранить их как varbinary.

Из статьи MSDN:

Операторы Transact-SQL могут вставлять, обновлять, запрашивать, искать и резервировать данные FILESTREAM. Интерфейсы файловой системы Win32 обеспечивают потоковый доступ к данным.
FILESTREAM использует системный кеш NT для кэширования данных файла. Это помогает уменьшить любой эффект, который данные FILESTREAM могут оказать на производительность компонента Database Engine. Буферный пул SQL Server не используется; поэтому эта память доступна для обработки запросов.

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

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

Хитрость в том, чтобы не стать фанатиком.

Здесь следует отметить, что никто в лагере профессиональных файловых систем не перечислил конкретную файловую систему. Означает ли это, что все от FAT16 до ZFS легко превосходит каждую базу данных?

Нет.

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

Правильный курс действий состоит в том, чтобы принять правильное решение для вашего точного сценария, и для этого вам понадобятся некоторые цифры и некоторые оценки вариантов использования.

В местах, где вы ДОЛЖНЫ гарантировать ссылочную целостность и соответствие ACID, требуется хранение изображений в базе данных.

Вы не можете гарантировать, что изображение и метаданные об этом изображении, хранящиеся в базе данных, ссылаются на один и тот же файл. Другими словами, невозможно гарантировать, что файл в файловой системе будет изменен только в одно и то же время и в той же транзакции, что и метаданные.

Как уже говорили другие, SQL 2008 поставляется с типом Filestream, который позволяет вам сохранять имя файла или идентификатор в виде указателя в БД и автоматически сохраняет изображение в вашей файловой системе, что является отличным сценарием.

Если вы используете более старую базу данных, то я бы сказал, что если вы храните ее как данные BLOB-объектов, то вы действительно не собираетесь ничего извлекать из базы данных для поиска функций, поэтому, вероятно, лучше сохранить адрес в файловой системе и сохранить изображение таким образом.

Таким образом, вы также экономите место в вашей файловой системе, так как вы собираетесь сэкономить только точное количество места или даже сжатое пространство в файловой системе.

Кроме того, вы можете решить сохранить с какой-либо структурой или элементами, которые позволяют вам просматривать необработанные изображения в вашей файловой системе без каких-либо ударов по БД, или переносить файлы в массе на другую систему, жесткий диск, S3 или другой сценарий - обновляя местоположение в ваша программа, но сохраняйте структуру, опять же, без особых усилий, пытаясь вывести изображения из вашей БД при попытке увеличить объем памяти.

Вероятно, это также позволит вам добавить некоторый элемент кэширования, основанный на часто используемых URL-адресах изображений, в ваш веб-движок / программу, так что вы сохраняете себя там же.

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

Обслуживание изображений из базы данных легко, просто реализуйте обработчик http, который обслуживает массив байтов, возвращаемый сервером БД, в виде двоичного потока.

Вот интересный документ по этой теме.

BLOB или не BLOB: хранение больших объектов в базе данных или файловой системе

Ответ: "Это зависит". Конечно, это будет зависеть от сервера базы данных и его подхода к хранилищу больших двоичных объектов. Это также зависит от типа данных, которые хранятся в BLOB-объектах, а также от способа доступа к ним.

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

Вот еще один момент, который нужно иметь в виду. Одной из причин, поддерживающих использование базы данных для хранения больших двоичных объектов, является соответствие требованиям ACID. Однако подход, использованный тестерами в техническом документе (опция Bulk Logged для SQL Server), который удваивал пропускную способность SQL Server, фактически изменил "D" в ACID на "d", поскольку данные большого двоичного объекта не регистрировались с помощью начальные записи для транзакции. Поэтому, если полное соответствие ACID является важным требованием для вашей системы, при сравнении операций ввода-вывода файлов и операций ввода-вывода в базе данных делите вдвое значения пропускной способности SQL Server для операций записи в базу данных.

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

Когда-то общее решение этого состоит в том, чтобы объединить их в сбалансированное дерево подкаталогов.

Что-то, что никто не упомянул, это то, что БД гарантирует атомарные действия, целостность транзакций и имеет дело с параллелизмом. Даже ссылочная целостность выходит за рамки с файловой системой - так как вы знаете, что ваши имена файлов действительно по-прежнему правильны?

Если у вас есть ваши изображения в файловой системе, и кто-то читает файл, когда вы пишете новую версию или даже удаляете файл - что произойдет?

Мы используем большие двоичные объекты, потому что ими проще управлять (резервное копирование, репликация, передача). Они хорошо работают для нас.

Проблема с хранением только файловых путей к изображениям в базе данных состоит в том, что целостность базы данных больше не может быть навязана.

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

Учитывая, что изображения являются фактическими запрашиваемыми данными, и что ими можно легче управлять (изображения не исчезнут внезапно) в одной интегрированной базе данных, а не взаимодействовать с какой-либо файловой системой (если к файловой системе осуществляется независимый доступ, изображения МОГУТ внезапно "исчезнуть"), я бы пошел на хранение их непосредственно как BLOB или что-то подобное.

В компании, в которой я работал, мы хранили 155 миллионов изображений в базе данных Oracle 8i (тогда 9i). 7,5 ТБ стоит.

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

Как и большинство других вещей, это зависит от ожидаемого размера и бюджета.

Мы внедрили систему обработки документов, которая хранит все свои изображения в полях BLOB-объектов SQL2005. На данный момент существует несколько сотен ГБ, и мы наблюдаем отличное время отклика и незначительное или полное снижение производительности. Кроме того, для соответствия нормативным требованиям у нас есть промежуточное программное обеспечение, которое архивирует вновь размещенные документы в оптическую систему музыкального автомата, которая представляет их в виде стандартной файловой системы NTFS.

Мы были очень довольны результатами, особенно в отношении:

  1. Простота репликации и резервного копирования
  2. Возможность легко внедрить систему управления версиями документов

Предположение: приложение доступно через Интернет

Я удивлен, что никто на самом деле не упомянул об этом... делегировать это другим специалистам -> использовать сторонний провайдер изображений / файловых хостингов.

Храните свои файлы на платном онлайн-сервисе, например

Другие потоки Stackru говорят об этом здесь.

В этой теме объясняется, почему вы должны использовать сторонний хостинг-провайдер.

Это того стоит. Они хранят это эффективно. Нет загрузки с ваших серверов на запросы клиентов и т. Д.

Если это веб-приложение, то могут быть преимущества хранения изображений в сторонней сети хранения данных, такой как Amazon S3 или платформа Nirvanix.

Если вы не используете SQL Server 2008 и у вас есть веские причины для размещения определенных файлов изображений в базе данных, вы можете использовать "оба" подхода и использовать файловую систему в качестве временного кэша и использовать базу данных в качестве основного хранилища.,

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

Недавно я создал приложение PHP/MySQL, которое хранит файлы PDF /Word в таблице MySQL (до 40 МБ на файл).

Плюсы:

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

Минусы:

  • mysqldump теперь занимает слишком долгое время, потому что в одной из таблиц содержится 500 МБ файловых данных.
  • В целом не очень эффективная память / процессор по сравнению с файловой системой

Я бы назвал мою реализацию успешной, она заботится о требованиях резервного копирования и упрощает макет проекта. Производительность хорошо для 20-30 человек, которые используют приложение.

Это зависит от количества изображений, которые вы собираетесь хранить, а также от их размеров. Я использовал базы данных для хранения изображений в прошлом, и мой опыт был довольно хорошим.

ИМО, Плюсы использования базы данных для хранения изображений,

A. Вам не нужна структура FS для хранения ваших изображений
B. Индексы базы данных работают лучше, чем деревья FS, когда нужно хранить больше элементов
C. Умно настроенная база данных хорошо справляется с кэшированием результатов запроса.
D. Резервные копии просты. Это также хорошо работает, если у вас есть настроенная репликация и контент доставляется с сервера рядом с пользователем. В таких случаях явная синхронизация не требуется.

Если ваши изображения будут маленькими (скажем, < 64 КБ), и механизм хранения вашей базы данных поддерживает встроенные (в записи) большие двоичные объекты, это еще больше повышает производительность, поскольку не требуется никакого косвенного обращения (достигается локальность ссылки).

Хранение изображений может быть плохой идеей, когда вы имеете дело с небольшим количеством изображений огромного размера. Другая проблема с хранением изображений в БД заключается в том, что метаданные, такие как создание, даты изменения должны обрабатываться вашим приложением.

Я не уверен, насколько это "реальный мир", но в настоящее время у меня есть приложение, в котором хранятся детали для карточной игры, включая изображения для карточек. Предполагается, что количество записей для базы данных на сегодняшний день составляет всего 2851 запись, но, учитывая тот факт, что некоторые карты выпущены несколько раз и имеют альтернативное оформление, на самом деле было более эффективно сканировать "первичный квадрат" рисунка, а затем динамически генерировать границы и различные эффекты для карты по запросу.

Первоначальный создатель этой библиотеки изображений создал класс доступа к данным, который отображает изображение на основе запроса, и делает это довольно быстро для просмотра и отдельной карты.

Это также облегчает развертывание / обновление при выпуске новых карт, вместо того, чтобы заархивировать целую папку с изображениями и отправить их по конвейеру и убедиться, что создана правильная структура папок, я просто обновляю базу данных и заставляю пользователя загружать ее снова. Это в настоящее время имеет размер до 56 МБ, что не очень хорошо, но я работаю над функцией постепенного обновления для будущих выпусков. Кроме того, существует версия приложения "без изображений", которая позволяет пользователям, подключенным к сети, получить приложение без задержки загрузки.

На сегодняшний день это решение отлично работает, поскольку само приложение предназначено для использования в качестве единственного экземпляра на рабочем столе. Существует веб-сайт, где все эти данные архивируются для онлайн-доступа, но я ни в коем случае не использовал бы одно и то же решение для этого. Я согласен, что доступ к файлам будет предпочтительнее, поскольку он будет лучше масштабироваться в зависимости от частоты и объема запросов к изображениям.

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

SQL Server 2008 предлагает решение, которое имеет лучшее из обоих миров: тип данных файлового потока.

Управляйте им как обычной таблицей и обладайте производительностью файловой системы.

По своему опыту я должен был управлять обеими ситуациями: изображения, хранящиеся в базе данных, и изображения в файловой системе с путем, сохраненным в БД.

Первое решение, изображения в базе данных, несколько "чище", поскольку вашему слою доступа к данным придется иметь дело только с объектами базы данных; но это хорошо только тогда, когда вам приходится иметь дело с небольшими цифрами.

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

С другой стороны, наличие больших двоичных объектов, хранящихся в файловой системе, приведет к тому, что у вас будут планы резервного копирования, которые должны учитывать как базу данных, так и файловую систему, и это может быть проблемой для некоторых систем.

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

При выборе этого варианта также учитывайте, должны ли вы иметь дело с разрешениями и аутентификацией при доступе к двоичным объектам: эти реквизиты обычно могут быть решены более простым способом, когда данные хранятся в БД.

Я когда-то работал над приложением обработки изображений. Мы сохранили загруженные изображения в каталоге, который был что-то вроде /images/[сегодняшняя дата]/[id номер]. Но мы также извлекли метаданные (exif-данные) из изображений и сохранили их в базе данных вместе с отметкой времени и тому подобным.

В предыдущем проекте я хранил изображения в файловой системе, и это вызывало множество головных болей, связанных с резервным копированием, репликацией и нарушением синхронизации файловой системы с базой данных.

В моем последнем проекте я храню изображения в базе данных и кэширую их в файловой системе, и это работает очень хорошо. У меня до сих пор не было проблем.

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

+ VES:

  • целостность базы данных
  • им легко управлять, так как вам не нужно беспокоиться о синхронизации файловой системы при добавлении или удалении изображения

-ves:

  • снижение производительности - поиск в базе данных обычно медленнее, чем поиск в файловой системе
  • Вы не можете редактировать изображение напрямую (обрезать, изменить размер)

Оба метода распространены и практикуются. Посмотрите на преимущества и недостатки. В любом случае вам придется подумать о том, как преодолеть недостатки. Хранение в базе данных обычно означает настройку параметров базы данных и реализацию некоторого вида кэширования. Использование файловой системы требует, чтобы вы нашли какой-то способ синхронизации файловой системы + базы данных.

Вторая рекомендация о путях к файлам. Я работал над парой проектов, которые требовали управления коллекциями активов большого размера, и любые попытки хранить вещи непосредственно в БД приводили к долговременным страданиям и разочарованию.

Единственное реальное "про", о котором я могу подумать в отношении хранения их в БД, - это возможность легкого использования отдельных изображений. Если нет путей к файлам, и все изображения передаются прямо из БД, нет опасности, что пользователь найдет файлы, к которым у него не должно быть доступа.

Похоже, что это было бы лучше решить с помощью промежуточного скрипта, извлекающего данные из недоступного в сети хранилища файлов. Таким образом, хранение БД НЕ ДЕЙСТВИТЕЛЬНО необходимо.

Уличное слово гласит: если вы не являетесь поставщиком баз данных и не пытаетесь доказать, что ваша база данных может это сделать (например, например, Microsoft хвастается тем, что Terraserver хранит изображения в виде баджиллиона в SQL Server), это не очень хорошая идея. Когда альтернатива - хранение изображений на файловых серверах и в базе данных путей намного проще, зачем беспокоиться? Поля блобов напоминают внедорожные возможности внедорожников - большинство людей их не используют, те, кто обычно попадают в неприятности, а есть и те, кто их использует, но только для удовольствия.

Другие вопросы по тегам