PHP для хранения изображений в MySQL или нет? - PullRequest
31 голосов
/ 09 февраля 2009

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

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

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

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

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

Ответы [ 16 ]

40 голосов
/ 09 февраля 2009

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

23 голосов
/ 09 февраля 2009

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

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

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

17 голосов
/ 19 декабря 2009

Затраты на использование 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).

16 голосов
/ 20 января 2012

вызов традиционной мудрости!

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

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

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

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

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

10 голосов
/ 09 февраля 2009

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

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

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

9 голосов
/ 09 февраля 2009

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

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

Так что просто сохраните путь к файлу изображения:)

6 голосов
/ 08 февраля 2013

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

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

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

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

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

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

Почему?

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

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

  • Упрощает масштабирование
  • Большинство браузеров не будут отправлять более двух запросов на один и тот же сервер, размещая статические данные на «втором» сервере, вы увеличиваете скорость загрузки
2 голосов
/ 09 февраля 2009

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

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

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