PHP для хранения изображений в MySQL или нет?

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

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

Кроме того, я пытался решить, лучше ли хранить изображение в таблице users MySQL в виде блоба или, может быть, отдельной таблицы images с уникальным идентификатором и просто сохранить соответствующий идентификатор изображения в таблице users , или просто сохраните загруженный файл на сервере (также через страницу загрузки) и сохраните файл как theUsersUniqueUsername.jpg . Лучший вариант?

Я нашел учебник по сохранению изображений в mysql здесь: http://www.phpriot.com/articles/images-in-mysql

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

Всегда зависит от контекста, но обычно я сохраняю изображение пользователя в файловой системе в папке с именем /content/user/{user_id}.jpg и стараюсь как можно меньше беспокоить базу данных.

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

Проверьте этот ответ тоже:

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

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

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

  • Не храните абсолютный URL-адрес файла в своей базе данных, просто уникальную часть (и, возможно, папку или две), например, 2009/uniqueImageName.jpg или просто uniqueImageName.jpg . Затем на ваших страницах просто добавьте хост и другие папки на передний план, таким образом, у вас есть определенная гибкость в перемещении изображений – все, что вам нужно изменить, это строка или две на вашей странице PHP / ASP.NET.

  • Нет необходимости хранить за пределами корня документа для обеспечения безопасности. Файл .htaccess с DENY FROM ALL будет работать одинаково и обеспечить большую гибкость

  • Не нужно так «тратить» изображения на безопасность, просто иметь страницу getImage.php или что-то в этом роде, а затем вместо того, чтобы вставлять фактический URL-адрес в src image , используйте что-то вроде getImage.php?file=uniqueImageName.jpg . Затем файл getImage.php может проверить, разрешен ли пользователь и захватить изображение (или нет).

  • Используйте имя, которое гарантировано будет уникальным (желательно целое, т.е. первичный ключ) при хранении, некоторые файловые системы (то есть Windows) не учитывают регистр, поэтому JoeBloggs.jpg и joebloggs.jpg уникальны для базы данных, но не для файловая система, поэтому перезаписать другую.

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

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

Борьба с традиционной мудростью!

Конечно, это зависит от контекста, но у меня очень большое приложение с тысячами изображений и документов, хранящихся в BLOBS в базе данных MySQL (средний размер = 2 МБ), и приложение отлично работает на сервере с 256 МБ памяти. Секрет – правильная структура базы данных. Всегда держите две отдельные таблицы, одна из которых хранит основную информацию о файле, а другая таблица должна содержать только blob плюс первичный ключ для доступа к нему. Все базовые запросы будут выполняться против таблицы подробностей, а другая таблица будет доступна только тогда, когда файл действительно необходим, и к нему обращаются с помощью индексированного ключа, так что производительность очень хорошая.

Преимущества хранения файлов в базе данных несколько:

  1. Нам нужны гораздо более простые системы резервного копирования, поскольку вам не нужно создавать резервные копии файловой системы
  2. Управление безопасностью файлов намного проще, чем вы можете проверить до выпуска двоичного файла (да, вы можете сохранить файл в непубличном каталоге и прочитать сценарий и перезапустить файл, но производительность не будет заметно быстрее.
  3. (Подобно # 1) Он четко разделяет «контент пользователя» и «системный контент», облегчая миграцию и клонирование.
  4. Легче управлять файлами, отслеживать / сохранять изменения версии и т. Д., Так как вам нужно меньше модификаций скриптов для добавления элементов управления версиями.

Если производительность – большая проблема, а безопасность и резервное копирование – нет (или если у вас хорошая резервная система fs), вы можете сохранить ее в FS, но даже тогда я часто храню файлы (в случае изображений) в БД и создание сценария кэширования, который записывает изображение в папку кэша после первого использования (да, это использует больше пространства HD, но это почти никогда не является ограничивающим фактором).

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

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

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

Это одна из тех вечных дебатов, с отличными аргументами с обеих сторон, но за мои деньги я буду держать образы от БД.

Недавно я увидел список этого совета: http://www.ajaxline.com/32-tips-to-speed-up-your-mysql-queries

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

Так что просто сохраните путь к файлу 🙂

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

  1. Хранилище файловой системы сложнее, когда кластеры кластеров приложений. У вас должно быть общее хранилище. Даже если ваша текущая среда не сгруппирована, это затрудняет масштабирование, когда вам нужно.
  2. Вы должны использовать CDN для своего статического контента в любом случае и устанавливать свое приложение в качестве источника. Это означает, что ваше приложение будет удалено только один раз для заданного изображения, затем оно будет кэшироваться на CDN. CloudFront – это дешевая и простая в установке, поэтому нет причин не использовать ее. Сохраните свою полосу пропускания для динамического контента.
  3. Это намного быстрее (и, следовательно, дешевле) для разработки сохраненных баз данных
  4. Вы получаете ссылочную целостность с сохраненными изображениями в базе данных. Если вы храните изображения в файловой системе, вы неизбежно будете иметь сиротские файлы без соответствующих записей базы данных, иначе у вас будут записи базы данных со сломанными ссылками на файлы. Это произойдет … это всего лишь вопрос времени. Вам нужно будет что-то написать, чтобы очистить их.

В любом случае, мои два цента.

  1. Каков тип данных blob в любом случае, если не для хранения файлов?
  2. Если ваше приложение связано с авторизацией до доступа к файлам, изменения заключаются в том, что вы: a) сохраняете файлы вне DOCUMENT_ROOT (поэтому к ним нельзя напрямую обращаться и, возможно, b) отправка всего содержимого файлов через приложение (конечно, возможно, вы делаете какую-то временную-перемещаемую-хэшированную, но общедоступную-файл). Таким образом, накладные расходы на память есть в любом случае, и вы также можете извлекать данные из базы данных.
  3. Если вы должны хранить файлы в файловой системе, сделайте, как предложил Андреас выше, и назовите их, используя то, что вы уже знаете (т. Е. Первичный ключ соответствующей таблицы).

Я думаю, что большинство движков баз данных уже настолько продвинуты, что хранение BLOB-данных не приводит к каким-либо недостаткам (раздутый db и т. Д.). Одно из преимуществ заключается в том, что у вас нет сломанных ссылок, когда изображение уже находится в базе данных. При этом я всегда делал это, чтобы сохранить файл на диске и предоставить URI базе данных. Это зависит от использования. Может быть проще обрабатывать img-in-db, если страница очень динамична и часто изменяется – без проблем пространства имен. Я должен сказать, что это заканчивается тем, что вы предпочитаете.

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

например, если у пользователя есть идентификатор 23, вы можете сохранить изображение в http://www.yourname.com/users/profile_images/23.jpg. Затем, чтобы отобразить, вы можете проверить, существует ли изображение, и отобразить его соответственно, иначе отобразите свой общий значок.

Как говорили другие:

  • Храните изображения в файловой системе
  • Не беспокойтесь, чтобы сохранить имя файла, просто используйте идентификатор пользователя (или что-нибудь еще, что «вы уже знаете»)
  • Поместите статические данные на другой сервер (даже если вы просто используете «static.yourdomain.com» в качестве псевдонима для вашего обычного сервера)

Зачем ?

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

Помещение статических данных на другой сервер (псевдоним):

  • Масштабирование намного проще
  • Большинство браузеров не отправят более одного запроса на один и тот же сервер, ставя данные на «втором» сервере, ускоряя загрузку

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

Это было просто здорово. У меня теперь есть 100% контроль над файлами, например управление доступом, размер изображения (я не масштабирую изображения динамически, конечно), статистику, резервное копирование и обслуживание.

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

Проверьте этот реальный пример, все еще находящийся в разработке, на узле SHARED, используя MVC: http://www.gt8.com.br/salaodocalcado/calcados/meia-pata/

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

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

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

Как все говорили вам, никогда не храните изображения в базе данных. Файловая система используется для хранения файлов -> изображений – это файлы -> хранить их в файловой системе 🙂

Просто проверил мой img как blob, так что. Это решение работает медленнее, чем изображения на сервере в виде файла. Время загрузки должно быть одинаковым с изображениями из DB или http, но is't. Зачем? Я уверен, что когда изображения являются файлами на сервере, браузер может кэшировать его и загружать только один раз, первый раз. Когда изображение, образующее БД, каждый раз загружается снова. Это мое оппонирование. Возможно, я ошибаюсь в отношении кеширования браузеров, но работает медленнее (blob). Пей мой английский, что угодно, P

Это плюсы обоих решений

В BLOBS:

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

2) Резервные копии БД также будут исчерпывающими.

В файлах

1) Ручное кэширование вручную (и это недостающая точка предыдущих комментариев, с обновлением и заголовками, которые вам не нужно будет переделывать в БД (DB не обрабатывает последнее время модификации по умолчанию)

2) Легкость изменения размера позже

3) Легкость модерации (просто просмотрите свои папки, чтобы проверить, все ли правильно)

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

В моем случае я храню файлы в файловой системе . В папке с изображениями я создаю новую папку для каждого элемента с именем на основе идентификатора элемента (строка из db). И назовите изображения в порядке, начиная с 0. Поэтому, если у меня есть таблица с именем Items like this:

  Items |-----|------|-----| | ID | Name | Date| |-----|------|-----| | 29 | Test1| 2014| |-----|------|-----| | 30 | Test2| 2015| |-----|------|-----| | 31 | Test3| 2016| |-----|------|-----| 

каталог моих изображений выглядит примерно так:

 images/ 29/ 30/ 31/ images/29/0.png images/29/1.jpeg images/29/2.gif 

и т.п.