Как лучше всего хранить загруженные изображения, базу данных SQL или файловую систему диска? - PullRequest
130 голосов
/ 08 декабря 2008

Я пишу приложение, которое позволяет пользователям загружать изображения на сервер. Я ожидаю около 20 изображений в день все в формате JPEG и, вероятно, не редактируются / изменяются размеры. (Это еще один вопрос, как изменить размер изображений на стороне сервера перед сохранением. Может быть, кто-то может добавить ресурс .NET для этого в комментарии или около того). Интересно, как лучше всего хранить загруженные изображения?

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

  • Или сохраните само изображение в таблице, используя тип данных «изображение» или «двоичные данные» сервера базы данных.

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

Ответы [ 19 ]

85 голосов
/ 08 декабря 2008

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

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

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

37 голосов
/ 26 ноября 2014

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

Если у вас нет уникального случая:

  • Бизнес-логика принадлежит коду.
  • Структурированные данные принадлежат базе данных (реляционной или нереляционной).
  • Объемные данные принадлежат хранилищу (файловая система или другое).

Files, Code, Data

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

https://uploadcare.com/upload-api-cloud-storage-and-cdn/

Но хранить файлы в базе данных - плохая идея.

21 голосов
/ 08 декабря 2008

Flickr использует файловую систему - они обсуждают причины здесь

11 голосов
/ 08 декабря 2008

У нас были клиенты, которые настаивали на выборе B (хранилище базы данных) несколько раз на нескольких разных бэкэндах, и мы всегда в конечном итоге возвращались к варианту A (хранилище файловой системы).

Такие большие BLOB просто не были обработаны достаточно хорошо даже в SQL Server 2005, который является последним, на котором мы его пробовали.

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

Еще одно замечание: если вы используете хранилище на базе NTFS (Windows Server и т. Д.), Вы можете подумать о том, как найти тысячи и тысячи файлов в одном каталоге. Я не уверен, почему, но иногда файловая система не справляется с этой ситуацией. Если кто-то знает об этом больше, я хотел бы услышать это.

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

Изображения / 2008/12/17 / .jpg

... Это обеспечивает достойный уровень разделения, а также немного помогает при отладке. Клиенты Explorer и FTP могут немного подавиться, когда действительно огромные каталоги.

РЕДАКТИРОВАТЬ: Просто краткое замечание за 2017 год, в более поздних версиях SQL Server появились новые опции для обработки большого количества больших двоичных объектов, которые, как предполагается, позволяют избежать описанных мною недостатков.

9 голосов
/ 08 декабря 2008

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

Плюсы:

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

Минусы:

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

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

7 голосов
/ 01 декабря 2016

Я знаю, что это старый пост. Но многие посетители этой страницы не получают ничего, связанного с этим вопросом. Специально для новичка.

Как загружать и хранить изображения или файлы на нашем сайте:

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

  1. Изображения поступают от администратора для динамического блога. Обычно эти изображения были оптимизированы перед загрузкой.

  2. Изображения от пользователей в случае пользователей разрешено загружать изображения, такие как аватар. Или пользователи могут создавать содержимое блога и добавлять изображения из текстового редактора. Этот вид изображений сложно предсказать размер. Пользователи могут загружать большие изображения только для небольшого контента, изменяя размер изображения, но не изменяя размер изображения.

При игнорировании пункта №. 1 выше, быстрое решение для пункта №. 2 может быть временно решено с помощью следующих советов, если у нас нет функции оптимизатора изображения на нашем сайте:

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

  2. Используйте функцию обрезки изображения для пользователей для загрузки изображений. Это ограничит размер изображения, даже если пользователи загружают очень большой файл. Окончательное изображение является результатом обрезанного изображения. Мы можем определить размер на стороне сервера и принять только, например, 500 КБ или ниже.

Теперь это только временно. Для окончательного решения вопрос повторяется:

  • Как обращаться с большим хранилищем изображений?
  • Изменить размер или изменить расширение.
  • Как большой или средний веб-сайт или электронная коммерция обрабатывают хранилище файлов для своих изображений?

Что мы можем сделать тогда:

  1. Миграция с общего хостинга VPS. Недостаточно? Тогда еще выше, повысив статус до Выделенного.

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

  3. Самый простой способ - воспользоваться службой хранения файлов CDN.

Хорошо, 1 и 2 немного дороже. Но нет 3, я думаю, это лучшее решение.

Некоторые сервисы CDN позволяют хранить столько веб-файлов, сколько вы хотите.

Вопрос: «Как загрузить файл в CDN с нашего сайта?»

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

Некоторые провайдеры предоставляют нам бесплатный сервис в течение 14 дней с ограниченным объемом памяти и пропускной способностью. Но это будет хорошо для отправной точки. Единственная проблема в том, что «люди никогда не пытаются».

Надеюсь, это поможет новичку.

6 голосов
/ 08 декабря 2008

Определенно измените размер изображения и, если возможно, проверьте его формат. Были случаи, когда вредоносные файлы загружались и обслуживались невольными хостами, например, уязвимость GIFAR позволяла скрыть вредоносный Java-апплет в GIF-файле, который затем мог читать файлы cookie в текущий контекст и отправьте их на другой сайт для атаки межсайтового скриптинга. Изменение размера изображений, как правило, предотвращает это, так как это влечет за собой встроенный код. Хотя эта атака была исправлена ​​исправлениями JVM, наивное обслуживание бинарных файлов без их очистки открывает вам целый ряд уязвимостей.

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

6 голосов
/ 08 декабря 2008

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

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

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

3 голосов
/ 29 июня 2016

Это в основном я.

  1. Сохранение загруженного изображения во временном каталоге или в памяти.
  2. Обработайте это изображение перед его постоянным сохранением. 2.1. Цветовые исправления 2.2. Компресс 2,3. Создайте несколько копий на основе размеров изображения 2,4. Переименовать с суффиксами .xl, .lg, .md, .sm и т. Д.
  3. Упакуйте все обработанные файлы изображений (из одного файла) в папку с именем папки как id, которое будет сохранено в базе данных для любой строки / документа вместе с image file name (или может быть случайным именем в качестве имени изображения) .
  4. Создать папку гггг / мм / д path, если она не существует. Например, 2016/08/21. Запомните этот путь и сохраните в базе данных тот же документ и строку.
  5. Переместить папку id в папку path. (Папка пути может находиться в папке / var / web-content.)
  6. Очистить буфер памяти или удалить временный файл.

Когда вам нужно получить доступ к любому изображению, упомянутому в документе, у вас есть путь и идентификатор папки, в которой содержатся изображения. Например /var/web-content/{{path}}/{{id}}/image-file-name.sm.jpg

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

3 голосов
/ 08 декабря 2008

Большинство реализаций - вариант А.

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

Я не думаю, что пространство - это слишком большая проблема ... Терабайтные накопители теперь стоят пару сотен долларов.

Мы реализуем с опцией A, потому что у нас нет времени или ресурсов, чтобы сделать опцию B.

...