Делать или не делать:Хранить изображения в базе данных [дублировать]

StackOverflow https://stackoverflow.com/questions/815626

  •  03-07-2019
  •  | 
  •  

Вопрос

На этот вопрос уже есть ответ здесь:

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

Единственная причина, о которой я могу думать, возможно, это более безопасно?Вы не хотите, чтобы у кого-то была прямая ссылка на URL-адрес?Но если это так, вы всегда можете попросить веб-сайт / сервер обрабатывать изображения, как обработчики в asp.net так что пользователю необходимо пройти аутентификацию для просмотра изображения.Я также думаю, что извлечение изображений из базы данных снизило бы производительность.Есть какие-либо другие причины, по которым может быть хорошей / не очень хорошей идеей хранить изображения в базе данных?


Точный Дубликат: Изображения пользователей:База данных или хранилище файловой системы?
Точный Дубликат: Хранение изображений в базе данных:Да или нет?
Точный Дубликат: Должен ли я хранить свои изображения в базе данных или папках?
Точный Дубликат: Будете ли вы хранить двоичные данные в базе данных или папках?
Точный Дубликат: Хранить изображения в виде файлов или базы данных для веб-приложения?
Точный Дубликат: Хранение небольшого количества изображений:blob или fs?
Точный Дубликат: хранить изображение в файловой системе или базе данных?

Это было полезно?

Решение

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

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

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

В остальном, не делай этого.

Другие советы

Плюсы размещения изображений в базе данных.

  1. Транзакции.Когда вы сохраняете большой двоичный объект, вы можете зафиксировать его точно так же, как любой другой фрагмент данных базы данных.Это означает, что вы можете зафиксировать большой двоичный объект вместе с любыми связанными метаданными и быть уверенным, что они синхронизированы.Если у вас закончится место на диске?Никаких обязательств.Файл загрузился не полностью?Никаких обязательств.Глупая ошибка приложения?Никаких обязательств.Если для вашего приложения важно поддерживать согласованность изображений и связанных с ними метаданных друг с другом, то транзакции, которые может предоставить база данных, могут стать благом.

  2. Одна система для управления.Нужно создать резервную копию метаданных и больших двоичных объектов?Создайте резервную копию базы данных.Нужно их воспроизвести?Реплицируйте базу данных.Нужно восстановиться после частичного сбоя системы?Перезагрузите базу данных и перенесите журналы вперед.Все преимущества, которые DBS предоставляют данным в целом (сопоставление томов, управление хранилищем, резервное копирование, репликация, восстановление и т.д.), применимы к вашим большим двоичным объектам.Больше согласованности, проще управление.

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

  4. Централизованное управление.Связано с # 2, но в основном администраторы баз данных (как будто у них недостаточно мощности) получают возможность управлять чем-то одним:база данных.Современные базы данных (особенно большие) очень хорошо работают при больших установках на нескольких компьютерах.Единый источник управления упрощает процедуры, упрощает передачу знаний.

  5. Большинство современных баз данных прекрасно обрабатывают большие двоичные объекты.Благодаря первоклассной поддержке больших двоичных объектов на вашем уровне данных вы можете легко передавать большие двоичные объекты из базы данных на клиент.Хотя существуют операции, которые вы можете выполнить, которые "засосут" весь большой двоичный объект сразу, если вам не нужно это средство, то не используйте его.Изучите интерфейс SQL для вашей базы данных и используйте его возможности.Нет причин относиться к ним как к "большим строкам", которые обрабатываются монолитно и превращают ваши двоичные объекты в большие бомбы, поглощающие память и разрушающие кэш.

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

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

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

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

Например, кто-то запрашивает spaceshuttle.jpg изображение, созданное 1 января 2009 года.Это в конечном итоге кэшируется в файловой системе на дату запроса, скажем, 1 февраля 2009 года.Позже изображение удаляется из кэша (политика FIFO или что-то еще), и кто-то позже, 1 марта 2009 года, запрашивает его снова.Что ж, теперь у него есть "дата создания" 1 марта 2009 года, хотя все это время его датой создания было действительно 1 января.Итак, вы можете видеть, особенно если ваш кэш часто обновляется, что клиенты, которые могут использовать заголовки If-Modified, могут получать больше данных, чем им на самом деле нужно, поскольку сервер ДУМАЕТ, что ресурс изменился, хотя на самом деле это не так.

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

Но суть в том, что это то, что нужно обдумать во всей проблеме, чтобы быть "хорошим гражданином Интернета" и потенциально сэкономить вам и вашим клиентам некоторую пропускную способность и т.д.

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

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

Например, на моей старой работе у нас было приложение, в котором пользователи прикрепляли изображения к нескольким различным пунктам отчета, который они писали, и эти изображения должны были быть распечатаны, когда это было сделано.Эти отчеты перемещались с помощью репликации SQL Server, и попытка управлять этими изображениями и путями к файлам в нескольких системах и серверах с какой-либо степенью надежности вызвала бы ОГРОМНУЮ головную боль.Хранение их в базе данных давало нам все это "бесплатно", и инструменту создания отчетов не нужно было обращаться к файловой системе для извлечения изображения.

Мой общий совет состоял бы в том, чтобы не ограничивать себя тем или иным подходом - используйте технику, которая соответствует ситуации.Файловые системы очень хороши в хранении файлов, а базы данных очень хороши в предоставлении небольших фрагментов данных по запросу.С другой стороны, в одном из продуктов моей компании есть требование хранить все состояние приложения в базе данных, что означает, что вложения файлов также попадают туда.С нашим сервером БД (SQL Server 2005) я еще не сталкивался с заметными проблемами производительности даже при работе с крупными клиентами и базами данных.

Microsoft SQL 2008 предоставляет вам лучшее из обоих миров с функцией FileStream - возможно, стоит проверить. http://technet.microsoft.com/en-us/library/bb933993.aspx

Одним из преимуществ хранения изображений в базе данных является то, что она переносима в разных системах и не зависит от расположения файловой системы (ов).

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

Предполагая, что ваш веб-сервер / сервер приложений и сервер базы данных - это разные машины, вы сделаете несколько заходов, поместив изображения в базу данных:(1) Задержка в сети между двумя компьютерами, (2) Накладные расходы на подключение к БД, (3) потребление дополнительного подключения к БД для каждого обслуживаемого изображения.Меня бы больше беспокоил последний пункт:если ваш сайт содержит много изображений, ваши веб-серверы будут потреблять много подключений к БД и могут исчерпать ваши пулы подключений.

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

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

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

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

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

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

Хранилище базы данных, как правило, дороже в обслуживании, чем файловая система, поэтому я бы не стал хранить МНОГО изображений в базе данных.

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

Просто не делай этого!

Это действительно похоже на проблему с ПОЦЕЛУЕМ (пусть это будет просто глупо).Файловые системы созданы для того, чтобы легко обрабатывать хранение файлов изображений, но это нелегко сделать в базе данных и легко испортить данные.Зачем снижать производительность и испытывать все трудности с sql и рендерингом, когда вы можете просто беспокоиться о безопасности файлов?Вы также можете обрабатывать смешанные системы с помощью NFS или CIFS.Файловые системы - это зрелые технологии.Гораздо проще, надежнее.

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

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

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

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

  • база данных для данных
  • файловая система для файлов
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top