Pull to refresh

Стоит ли хранить файлы в БД MySQL?

Reading time3 min
Views7.8K
Споры по данной теме мне приходилось наблюдать на нескольких форумах, порой даже по нескольку раз. В основном эти темы касались хранения изображений, реже текстовых файлов. Сам я отношусь к противникам данного метода и в статье попытаюсь привести обоснованные доказательства того, что хранить файлы в БД неудобно и негативно влияет на скорость работы системы в целом. Поскольку в основном я работаю с MySQL, то и рассматривать данный вопрос буду с точки зрения хранения файлов в его базах при разработке под WEB.


1. ОЗУ. Самым главным аргументом против, на мой взгляд, является тот факт, что даже когда файл нужно просто отдать пользователю (например отобразить изображение) его все равно придется загружать в ОЗУ, т.к. все данные выбранные запросом из БД загружаются в оперативную память. На момент написания данной статьи самым дорогим, после процессора, на выделенных серверах является ОЗУ. При этом я уже не говорю про обычный хостинг где в подавляющем большинстве случаев под каждый аккаунт выделяется определенное количество оперативной памяти, превышение которой приводит к «Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)» либо к гневным письмам из саппорта.

2. Отдача файлов. Если файлы хранятся в БД, то для их отдачи в любом случае придется использовать скрипт написанный на том или ином языке, который должен сделать следующее:
2.1 Открыть новое соединение с БД, количество которых далеко не бесконечно, либо занять уже существующее но свободное соединение, что плохо по той же причине;
2.2 Запросом выбрать содержимое файла из таблицы. Тут возникает сразу 2-е проблемы:
2.2.1 Загрузка содержимого файла в ОЗУ (см. п. 1);
2.2.2 По какому параметру искать файл в БД. Логично предположить что самым быстрым будет поиск по целочисленному ID, но в таком случае в ссылке на скрипт выдачи файла так же нужно будет использовать этот ID (например: <img src='./getimage.php?id=1111'>), что в случае формирования таких ссылок вручную затруднит работу.
2.3 Отдать необходимые хидеры и содержимое файла.
И все эти шаги будут проделываться для каждого файла, а если их на странице выводиться штук 20, причем загрузка идет одновременно, то есть риск не увидеть ни одного.
Так же такой способ хранения файлов практически лишает вас следующих возможностей:
— распределить файлы по нескольким серверам и для скачки давать ссылки непосредственно на эти сервера;
— установить reverse proxy server для ускорения «медленных клиентов»
— использовать CDN.

3. Дампы. Одним из аргументов «за» часто приводят следующее: «Если мне понадобится перенести сайт на другой хостинг, то мне нужно только сделать дамп и скопировать код». Лично я не считаю этот аргумент весомым по следующим причинам:
3.1 Давайте наконец начнем писать сайты так, чтобы они быстро работали, а не только чтобы они легко переносились;
3.2 Хранение любых, а особенно бинарных файлов в БД приводит к следующему:
3.2.1 т.к. увеличивается БД то соответственно увеличивается время для создания ее дампа и его размер;
3.2.2 наличие в дампе содержимого бинарного файла очень ухудшает его читабельность, а так ж, что немаловажно, далеко не все консольные редакторы могут открыть большой дам для редактирования, например MCEDIT не может;
3.2.3 с большой вероятностью возникнут проблемы с заливкой такаих дампов:
— во-первых, это будет достаточно долгий процесс;
— во-вторых, это может оказаться достаточно сложно, особенно если сайт располагается на хостинге, который не позволяет конектиться к БД извне и не дает доступа к серверу по ssh для того, чтобы можно было воспользоваться тулзой «mysql». В этом случае Вам придется использовать скрипты вроде phpMyAdmin (хотя по своему опыту работы с ним могу с почти 100% уверенностью сказать, что через него залить дамп больших размеров 50 100 мб задача почти нереальная) или Sypex Dumper.

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

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

Вот вроде и все, но хочу еще раз напомнить, что я рассматривал данный вопрос со стороны программирования под web, а именно для MySQL. При этом я осознаю, что для других областей программирования и других СУБД, таких как MSSQL и Oracle все или часть моих доводов могут оказаться неверны.
Tags:
Hubs:
Total votes 17: ↑12 and ↓5+7
Comments41

Articles