Как хранить файлы в базе данных

Обновлено: 21.11.2024

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

Итак, вы ищете, как сохранять файлы в MongoDB (или PostgreSQL, MySQL и т. д.), только для того, чтобы узнать, что хранение файлов в базе данных считается плохой практикой.

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

Но никто не говорит вам почему.

Это потому, что очень длинная строка base64 в базе данных выглядит плохо?

Это должно быть нечто большее.

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

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

🔗Недостатки хранения файлов в базе данных

🔗Запросы к базе данных медленнее

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

Кроме того, файлы занимают ОЗУ, которое используется базой данных для повышения производительности. Часто используемые данные хранятся в оперативной памяти, так как она обеспечивает гораздо более быстрое чтение, чем дисковое хранилище.

Запрос файлов, скорее всего, означает, что база данных в конечном итоге сохранит эти файлы в ОЗУ. Серверы обычно ограничены объемом доступной оперативной памяти, поэтому база данных в конечном итоге отдает приоритет одним данным над другими. Данные, которые не хранятся в ОЗУ, приходится считывать с диска, что всегда намного медленнее, чем ОЗУ.

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

🔗Поддерживать базу данных становится сложнее

Администраторы баз данных согласятся на это:

Уровень знаний, необходимый для обслуживания базы данных, повышается пропорционально размеру базы данных.

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

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

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

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

🔗Хранить и обслуживать файлы сложнее

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

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

Примечание. Файлы, хранящиеся в формате base64, занимают на 33 % больше места, чем их первоначальный размер.

Хранение файлов в виде двоичных файлов в базе данных имеет аналогичный недостаток — двоичные данные экранируются/кодируются в приложении перед их отправкой в ​​базу данных.

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

🔗Другие недостатки

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

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

Ограничения базы данных. Размер документов MongoDB ограничен 16 МБ. Если вы хотите хранить большие файлы в MongoDB, вам нужно использовать GridFS. В PostgreSQL столбцы ограничены 1 ГБ на строку. Если файл, который вы хотите сохранить, больше, вы должны использовать специальную таблицу, предназначенную для хранения больших объектов.

🔗Где вместо этого хранить файлы?

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

🔗Файловая система

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

Node.js имеет встроенный модуль fs (fs/promises с async/await), который упрощает взаимодействие с файловой системой. Кроме того, есть несколько удобных библиотек, таких как fs-extra и findit, которые упрощают выполнение обычных задач.

Помните, что поставщики платформы как услуги, такие как Heroku, AWS Elastic Beanstalk и платформа приложений DigitalOcean, имеют эфемерную/короткоживущую файловую систему. Любые файлы, сохраненные локально, исчезнут после развертывания или перезапуска приложения. Поэтому вы не можете полагаться на файловую систему для хранения файлов, которые должны сохраняться в течение более длительного времени. Используйте VPS, если хотите хранить файлы локально или вместо этого храните файлы в облаке.

🔗Облачное хранилище

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

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

AWS S3. Amazon Web Services (AWS) имеет наибольшую долю рынка в облачной индустрии, и их решение для хранения данных называется S3. В AWS S3 файлы называются объектами и хранятся в корзинах, которые представляют собой уникальные пространства имен URL. S3 не знает концепции папок, потому что файловая система абстрагирована. Используйте косую черту ( / ) в именах файлов, и вы получите навигацию по папкам на панели инструментов S3.

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

Пространства DigitalOcean. DigitalOcean известен своей обширной коллекцией высококачественных ресурсов. Все, что связано с DevOps, они вам помогут. Мне они нравятся за их чистый и интуитивно понятный пользовательский интерфейс. DigitalOcean Spaces совместим с AWS S3, поэтому у них схожая концепция объектов и сегментов/пространств.

Backblaze B2 похож на AWS S3, но в несколько раз дешевле. Они известны тем, что пишут надежное программное обеспечение, ориентированное на безопасность и шифрование. Backblaze также может постоянно создавать резервные копии вашего ноутбука в облаке, которым я с удовольствием пользуюсь уже много лет.

🔗Означает ли это, что вы никогда не должны хранить файлы в базе данных?

Нет. Ответ, как всегда, зависит от обстоятельств.

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

🔗Обзор

  • Запросы к базе данных медленнее
  • Обслуживание базы данных становится более сложным
  • Хранить и обслуживать файлы сложнее

Кроме того, вы можете хранить файлы в файловой системе или в облаке, что больше соответствует передовым отраслевым практикам. AWS S3, DigitalOcean Spaces, Cloudinary и Backblaze B2 — популярные облачные платформы в сообществе Node.js.

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

🔗Назад к вам

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

Что бы вы ни решили, теперь у вас есть все необходимое для принятия более мудрого решения, чем раньше.

В настоящее время я создаю веб-приложение, которое позволяет пользователям хранить и обмениваться файлами размером от 1 МБ до 10 МБ.

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

Действительно ли это? Лучше ли хранить файлы в файловой системе и сохранять имя файла и путь в базе данных? Существуют ли какие-либо рекомендации по хранению файлов при работе с базой данных?

Удивлен, что никто не опубликовал исследование MS, проведенное по этому вопросу (для SQL Server 2008): в BLOB или не в BLOB: хранилище больших объектов в базе данных или файловой системе

большой – это относительная величина, я (и, возможно, многие другие) не считаю 10 МБ такими большими в современной системе.

В соответствии с часто задаваемыми вопросами это относится к теме и соответствует пунктам "шаблоны проектирования" (антишаблоны с косой чертой) и "архитектура программного обеспечения". Почему закрыли?

13 ответов 13

Причины в пользу хранения файлов в базе данных:

  1. Консистенция ACID, включая откат обновления, что усложняется, когда файлы хранятся вне базы данных. Это не должно быть приукрашено слегка. Синхронизация файлов и базы данных и возможность участвовать в транзакциях могут быть очень полезными.
  2. Файлы идут вместе с базой данных и не могут быть изолированы от нее.
  3. Резервные копии автоматически включают двоичные файлы файлов.

Причина против хранения файлов в базе данных:

  1. Размер двоичного файла зависит от базы данных. Например, в SQL Server, когда объект FILESTREAM не используется, он составляет 2 ГБ. Если пользователям нужно хранить файлы большего размера (например, фильмы), вам придется прыгать через обручи, чтобы это волшебство произошло.
  2. Увеличивает размер базы данных. Одна общая концепция, которую вы должны принять во внимание: Уровень знаний, необходимых для обслуживания базы данных, возрастает пропорционально размеру базы данных. То есть, большие базы данных сложнее поддерживать, чем маленькие базы данных. Хранение файлов в базе данных может сделать базу данных намного больше. Даже если, скажем, было бы достаточно ежедневного полного резервного копирования, при большем размере базы данных вы больше не сможете этого делать. Возможно, вам придется подумать о том, чтобы поместить файлы в другую файловую группу (если база данных поддерживает это), настроить резервные копии, чтобы отделить резервную копию данных от резервной копии файлов и т. д. Ни одна из этих вещей невозможна для изучения, но сделайте усложняют обслуживание, что означает затраты для бизнеса. Большие базы данных также потребляют больше памяти, так как пытаются втиснуть в память как можно больше данных.
  3. Переносимость может стать проблемой, если вы используете системные функции, такие как объект FILESTREAM SQL Server, и вам необходимо перейти на другую систему баз данных.
  4. Проблемой может быть код, который записывает файлы в базу данных. Одна компания, для которой я консультировал не так много лун назад, в какой-то момент подключила интерфейс Microsoft Access к своему серверу базы данных и использовала возможность Access загружать «что угодно», используя свой элемент управления Ole Object. Позже они изменились, чтобы использовать другой контроль, который все еще полагался на Оле. Гораздо позже кто-то изменил интерфейс для хранения необработанного двоичного файла. Извлечение этих Старых Объектов было новым уровнем ада. Когда вы храните файлы в файловой системе, не требуется дополнительный слой для переноса/настройки/изменения исходного файла.
  5. Отправлять файлы на веб-сайт сложнее. Чтобы сделать это с двоичными столбцами, вам нужно написать обработчик для потоковой передачи двоичного файла из базы данных. Вы также можете сделать это, даже если вы храните пути к файлам, но вам необходимо это делать. Опять же, добавление обработчика не является невозможным, но добавляет сложности и является еще одной точкой отказа.
  6. Вы не можете использовать преимущества облачного хранилища. Предположим, однажды вы захотите хранить свои файлы в корзине Amazon S3. Если вы храните в базе данных пути к файлам, вам предоставляется возможность изменить их на пути на S3. Насколько мне известно, это невозможно ни в одном сценарии с любой СУБД.

IMO, считая хранение файлов в базе данных или не "плохим", требует дополнительной информации об обстоятельствах и требованиях. Всегда ли размер и/или количество файлов будут небольшими? Нет планов использовать облачное хранилище? Будут ли файлы размещены на веб-сайте или в двоичном исполняемом файле, таком как приложение Windows?

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

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

@BillyONeal. В каком-то смысле ваш комментарий был лучшим ответом. Вы можете пользоваться всеми преимуществами хранилища БД, но не иметь проблем.

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

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

Однако! Некоторые базы данных, такие как SQL Server, имеют тип столбца FILESTREAM. В этом случае ваши данные фактически хранятся в отдельном файле на сервере базы данных, а в таблице сохраняется только идентификатор файла. В этом случае я не вижу особых причин не хранить данные на сервере SQL. Файлы автоматически включаются в резервную копию сервера, а база данных и файлы всегда синхронизируются. Проблема с предложением Тони хранить имена файлов заключается в том, что база данных и файловая система могут рассинхронизироваться. База данных будет утверждать, что файл существует, когда он был удален с диска. Если процесс изменяет базу данных, а затем происходит сбой, файлы и база данных не будут совпадать (т. е. не будет ACID с файлами вне базы данных).

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

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

Другие возможные проблемы с методом File/DB: 1) вы должны выполнять обновления как копирование при записи. Если ваш процесс рухнет во время обновления, статус БД будет откатан, а файл - нет. 2) Для этого требуется какая-то сборка мусора из старого файла. 3) Хранение всего в БД означает, что версии БД и файлы синхронизируются после резервного копирования. Восстановите свою БД до состояния 2-недельной давности. теперь что, где содержимое файлов в то время?

@briddums — Нет, поскольку SQL Server интегрируется непосредственно в файловую систему и управляет этими файлами от имени ОС. Я не использовал их сам, но документация показывает, что FILESTREAM и его потомки FileTables предоставляют вам лучшее из обоих миров: файлы тесно связаны с базой данных и связанными данными (что позволяет вам централизованно управлять своими данными) без раздувания база данных.

Я согласен с Ником. Мы заменили нашу систему Диск+БД на столбцы FILESTREAM и никогда не оглядывались назад. Очень приятно иметь возможность привязывать файлы к другим таблицам через FK. Таким образом, вы можете сказать, что "каждый человек должен иметь один или несколько связанных с ним документов отдела кадров" или что-то в этом роде.

Да, это плохая практика.

Влияние на производительность БД:

  • если вы выполняете SELECT с любым столбцом BLOB, вы всегда будете обращаться к диску, а без BLOB у вас есть возможность получить данные прямо из ОЗУ (БД с высокой пропускной способностью будет оптимизирована для размещения таблиц в ОЗУ);
  • Репликация будет медленной, а задержка репликации высокой, так как BLOB придется передавать подчиненным устройствам. Высокая задержка репликации будет вызывать всевозможные условия гонки и другие проблемы с синхронизацией, если только вы явно не примете это во внимание;
  • Резервное копирование/восстановление БД займет намного больше времени;

Преимущество в скорости — нет! В то время как некоторые старые файловые системы плохо справляются с каталогами с миллионами файлов, у большинства современных проблем нет вообще, и они фактически используют те же структуры данных, что и BD (обычно B-деревья). Например, ext4 (файловая система Linux по умолчанию) использует Htree.

Вывод: это снизит производительность вашей БД и не улучшит скорость поиска файлов.

Кроме того, поскольку вы говорите о веб-приложении, обслуживание статических файлов непосредственно из файловой системы с использованием современного веб-сервера, который может выполнять системный вызов sendfile(), значительно повышает производительность. Это, конечно, невозможно, если вы извлекаете файлы из БД. Рассмотрим, например, этот тест, показывающий, что Ngnix выполняет 25 000 запросов в секунду с 1000 одновременных подключений на низком ноутбуке. Такая нагрузка поджарит любую БД.

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

@BillyONeal: почему вы предполагаете, что у вас должен быть один и тот же сервер для статического и динамического контента? Что касается синхронизации файлов между серверами, то для этого есть специальные инструменты, гораздо более эффективные, чем базы данных. Использование базы данных в качестве файлового сервера похоже на попытку забить гвоздь отверткой.

@BillyONeal: Я согласен, что есть некоторые «решения», где это сработает, я видел довольно много любительских настроек PHP с изображениями в MySQL. Однако при такой настройке БД никогда не будет поддерживать большой трафик, обслуживающий большие двоичные объекты.

Я бы отнесся к этому прагматично и следовал бы принципу "пока не оптимизировать".Сделайте решение, которое имеет смысл в данный момент, и решение, для правильной реализации которого у вас есть ресурсы разработки. Есть много потенциальных проблем. Но они не обязательно становятся реальными проблемами. Например. Вероятно, это не будет проблемой, если у вас будет 100 пользователей. Это может быть проблемой, если у вас 100 000 или 10 000 000 пользователей. Но в последнем случае должна быть основа для большего количества ресурсов на разработку для решения всех проблем.

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

Лично я бы предпочел хранить данные в базе данных, но убедиться, что BLOBS не считываются до тех пор, пока они действительно не понадобятся, то есть не выполняется "SELECT * FROM . " для тех таблиц, содержащих блоги. И я бы позаботился о том, чтобы дизайн позволял легко перемещать данные из базы данных в файловую систему, если у вас возникнут проблемы с производительностью. Например, храните информацию о файле в отдельной таблице File, тем самым защищая информацию о файле от других бизнес-объектов.

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

С незапамятных времен поставщики баз данных призывали разработчиков: «Храните все в базе данных. Ты знаешь чего хочешь. Здесь мы упростим вам задачу, добавив такие типы данных, как двоичные файлы, и такие функции, как файловый поток».

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

Пользователи хотят хранить исторические версии файлов. Вначале в требованиях к дизайну может быть указано сохранение только самой последней версии файла, но это изменится. Пользователи со временем захотят сохранить каждую версию — и даже если они этого не сделают, они будут создавать «новые» файлы, сохраняя их под немного другим именем. Вы знаете этот файл 2022_Budget_Final_v2_with_Changes.xlsx и все его прародители? Да, они все живут в базе данных навсегда.

Пользователи часто создают новые версии. Вы знаете, как вы все время нажимаете «Файл», «Сохранить», потому что вы привыкли к дрянным приложениям, которые вылетают и теряют ваш прогресс? Теперь подумайте о том, что каждый раз приходится обращаться к серверу реляционной базы данных, умноженному на всех пользователей, работающих в этой системе.

Поверь мне, у меня есть шрамы

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

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

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

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

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

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

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

Есть лучший способ:
хранить файлы в файловой системе.

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

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

Потому что, если вы не выполняете с ней реляционное соединение,
она не принадлежит реляционной базе данных.

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

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

Если вы предпочитаете хранить файлы в файловой системе, полагая, что файловая система была создана для хранения файлов, или если вас не беспокоят преимущества использования базы данных для сохранения файлов в определенных сценариях, то пришло время пересмотри свой выбор, мой друг! Это связано с тем, что современные СУБД ориентированы на улучшение хранения больших двоичных объектов.

Давайте рассмотрим плюсы и минусы сохранения файлов в файловой системе и базе данных.

Плюсы файловой системы:

  • Производительность может быть лучше, чем в БД. Чтобы оправдать это, если вы храните большие файлы в базе данных, это может снизить производительность, потому что простой запрос для получения списка файлов или имени файла также загрузит данные файла, если вы использовали Select * в своем запрос. В то время как файловая система получает доступ к файлу довольно просто и легко.
  • Сохранение файлов и их загрузка в файловую систему намногопроще, чем в базу данных, так как вам поможет простая функция Сохранить как. Загрузку можно выполнить, указав URL-адрес с указанием местоположения сохраненного файла.
  • Миграция данных является простым процессом. Вы можете просто скопировать и вставить папку в нужное место, убедившись, что для места назначения предоставлены права на запись.
  • Экономично, поскольку экономично в большинстве случаев расширять веб-сервер, а не платить за определенные базы данных.
  • Его легко перенести в облачное хранилище, такое как Amazon S3 или CDN и т. д. в будущем.

Минусы файловой системы:

  • Неплотно упакован . НетACID(Atomicity, Consistency, Isolation, Durability) операции реляционного отображения, которые значит нет гарантии. Рассмотрим сценарий, если ваши файлы удалены из местоположения вручную или какими-то хакерами, вы можете не знать, существует ли файл или нет. Больно, правда?
  • Низкий уровень безопасности . Поскольку ваши файлы могут быть сохранены в папке, в которой вы должны были предоставить права на запись, это может привести к проблемам с безопасностью и вызвать такие проблемы, как взлом. Поэтому лучше избегать сохранения в fs, если вы не можете позволить себе идти на компромисс с точки зрения безопасности.

Когда это наиболее предпочтительно:

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

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

Плюсы базы данных:

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

Минусы базы данных:

  • Возможно, вам придется преобразовать файлы вBLOB, чтобы сохранить их в БД.
  • База данных Резервные копии станет более тяжелой и тяжелой.
  • Память неэффективна . Чтобы добавить больше, часто РСУБД управляются оперативной памятью. Таким образом, все данные должны сначала попасть в оперативную память. Да, это так. Вы когда-нибудь задумывались о том, что происходит, когда РСУБД должна найти и отсортировать данные? РСУБД отслеживает каждую страницу данных, даже самый низкий объем считанных/записанных данных, и она должна отслеживать, находятся ли они в памяти или на диске, индексируются ли они или сортируются физически и т. д.

P.S. Я пропустил некоторые противоречивые моменты, чтобы сократить содержание, потому что при сравнении двух вещей мы часто обнаруживаем, что плюсы и минусы одного будут противоположны другому.

Когда это наиболее предпочтительно:

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

Лучший способ:

  • Будьте осторожны с запросом Select, избегайте нежелательных запросов Select *, которые могут часто извлекать данные файла без необходимости.
  • Кэширование данных файла позволяет сократить использование памяти и базы данных.
  • Если вы используете SQL Server 2008 или более позднюю версию, используйте FILESTREAM.

Filestream позволяет хранить данные BLOB в NTFS и в то же время обеспечивает согласованность транзакций между неструктурированными данными Blob и структурированными данными в базе данных.

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

Прочитав этот довольно большой блог с большим терпением, вы можете обнаружить, что я еще не указал, какой из них лучше. Итак, в заключение ответ: «Это зависит».

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

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

Однако адаптация к функции Filestream SQL Server 2008 может быть достойной попыткой. Итак, мы в Habile инициировали включение файлового потока. Мы призываем вас сделать то же самое, если вы можете себе это позволить.

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

Читайте также: