Должен ли я использовать тип поля blob MySQL?

Я пытаюсь решить, должен ли я использовать тип поля blob MySQL в предстоящем проекте, который у меня есть.

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

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

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

Есть ли производительность с использованием типа поля blob MySQL? Я обеспокоен выбором решения, которое будет препятствовать будущему росту веб-сайта, а также выбирая решение, которое будет легко поддерживать.

Ответ 1

Если ваш веб-сервер будет обслуживать эти загруженные файлы через Интернет, производительность почти наверняка будет лучше, если они будут сохранены в файловой системе. Затем веб-сервер сможет применять подсказки кэширования HTTP, такие как Last-Modified и ETag, что поможет производительности для пользователей, обращающихся к одному и тому же файлу несколько раз. Кроме того, веб-сервер автоматически установит правильный Content-Type для файла при обслуживании. Если вы храните капли в базе данных, вы в конечном итоге реализуете вышеупомянутые функции и многое другое, когда вы должны получать их бесплатно с вашего веб-сервера.

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

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

Ответ 2

Есть ли производительность с использованием типа поля blob MySQL?

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

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

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

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

Если вы используете файловую систему, а не blob, возникает вопрос: вы хотите, чтобы веб-сервер обслуживал его, указав псевдоним в папке?

  • + супер быстрый
  • + хорошо кэширует
  • - дополнительная конфигурация сервера: виртуальный каталог; требуется соответствующее расширение файла для возврата желаемого Content-Type
  • - дополнительная конфигурация сервера: нужно добавить заголовки Content-Disposition: attachment/X-Content-Type-Options, чтобы остановить IE, нюхание для HTML как часть мер анти-XSS

или вы обслуживаете файл вручную, если серверная сторона script выплюнула его, как вам нужно будет работать с блобом MySQL?

  • - потенциально медленный
  • - требуется справедливая часть ручного управления If-Modified-Since и ETag для правильного кэширования
  • + может использовать собственные методы контроля доступа приложения
  • + легко добавить правильные заголовки Content-Type и Content-Disposition из обслуживающего script

Это компромисс не на один глобально принятый ответ.

Ответ 3

По моему опыту, хранение BLOB в MySQL в порядке, так как вы сохраняете только blob в одной таблице, а другие поля находятся в другой (объединенной) таблице. И наоборот, поиск в полях таблицы с несколькими стандартными полями и одним блоком blob с 100 МБ данных может резко замедлить запросы.

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

Ответ 4

Большие объемы данных в конечном итоге скажутся на производительности. MS SQL 2008 имеет специализированный способ хранения двоичных данных в файловой системе:

http://msdn.microsoft.com/en-us/library/cc949109.aspx

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

Вы можете создать таблицу FILES, которая будет хранить информацию о файлах, таких как, например, оригинальные имена. Чтобы безопасно хранить файлы на диске, переименуйте их, например, с помощью GUID. Сохраните новые имена файлов в таблице FILES, и когда пользователь загрузит их, вы можете легко найти его на диске и передать его пользователю.

Ответ 5

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

  • Резервное копирование базы данных и баз данных меньше.
  • Легче редактировать файлы в файловой системе, если вам нужно работать с ними ad hoc.
  • Файловые системы умеют хранить файлы. Базы данных хороши для хранения кортежей. Пусть каждый делает то, что хорошо.

Также существуют встречные аргументы, которые поддерживают вложение вложений в blob:

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

Таким образом, лучшее решение зависит от того, как вы собираетесь использовать данные в своем приложении. Нет ответа на один размер.

Я знаю, что вы отметили свой вопрос в MySQL, но если люди, читающие этот вопрос, используют другие бренды РСУБД, они могут захотеть изучить BFILE при использовании Oracle или FILESTREAM при использовании Microsoft SQL Server 2008. Они дают вы можете хранить файлы за пределами базы данных, но обращаться к ним так, как будто они являются частью строки в таблице базы данных (более или менее).

Ответ 6

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

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

Ответ 7

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