Какое место лучше всего подходит для хранения загруженных изображений, база данных SQL или дисковая файловая система?

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

Вопрос

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

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

  • Или сохраните само изображение в таблице, используя тип данных "image" или "binary data" сервера базы данных.

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

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

Решение

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

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

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

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

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

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

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

Files, Code, Data

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

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

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

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

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

Подобные большие двоичные объекты просто недостаточно хорошо обрабатывались даже SQL Server 2005, на котором мы опробовали это последней версией.

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

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

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

Images/2008/12/17/.jpg

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

Редактировать: Просто краткое замечание за 2017 год: в более поздних версиях SQL Server появились новые опции для обработки большого количества больших двоичных объектов, которые, как предполагается, позволят избежать недостатков, которые я обсуждал.

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

Плюсы:

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

Минусы:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ладно, 1 и 2 немного дороговаты.Но № 3, я думаю, является лучшим решением.

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

Вопрос: "как загрузить файл в CDN с нашего веб-сайта?"

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

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

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

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

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

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

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

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

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

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

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

Мы внедряем вариант А, потому что у нас нет времени или ресурсов для реализации варианта B.

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

В SQL Server 2008 существует своего рода гибридный подход, называемый тип данных filestream об этом говорилось на Радио РунАс #74, что в некотором роде является лучшим из обоих миров.У большинства людей нет версии 2008, но если у вас есть, этот вариант выглядит довольно круто

В принципе, это то, чем я занимаюсь.

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

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

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

Мы используем A.Я бы поместил его на общий диск (если только вы не планируете запускать более одного сервера).

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

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

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

Вариант A.

Как только изображение загружено, вы можете проверить формат и изменить его размер перед сохранением.Существует несколько .Примеры сетевого кода для изменения размера изображений на http://www.codeproject.com.Например: http://www.codeproject.com/KB/cs/Photo_Resize.aspx

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

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

Я надеюсь, что это поможет вам.

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

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

В большинстве случаев это вопрос предпочтений, но если вы выберете вариант А, просто убедитесь, что в каталогах не слишком много файлов.Если вы выберете вариант B, то сделайте так, чтобы таблица с выделенными данными находилась в ее собственной базе данных и / или файловой группе.Это поможет в обслуживании, особенно при резервном копировании / восстановлении.Ваши обычные данные, вероятно, довольно малы, в то время как ваши данные изображения будут Огромный со временем.

Это зависит от ваших требований, особенно от объема, пользователей и частоты поиска.Но для небольшого или среднего офиса лучшим вариантом является использование такого приложения, как Apple Photos или Adobe Lighroom.Они специализированы для хранения, каталогизации, индексирования и организации такого рода ресурсов.Но для крупных организаций с высокими требованиями к хранилищу и большим количеством пользователей рекомендуется создать платформу управления контентом с помощью системы управления цифровыми активами, такой как Nuxeo или Alfresco;оба предложения очень хороших ресурсов управляют очень большими объемами данных с помощью упрощенных методов их повторного поиска.И, что очень важно:существует бесплатный вариант (с открытым исходным кодом) для обеих платформ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top