Как лучше хранить много файлов — в базе данных или в виде файлов?

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

Отсюда вопросы:

— где лучше хранить все эти файлы — в виде Blob/text в MySql или же в виде отдельных файлов на диске? Сами файлы напрямую клиентам отдаваться не будут — сначала они обрабатываются специальным php скриптом и только потом результат обработки отдается. Для каждого клиента результат может быть разным (а может быть и таким же)

— как лучше все это потом бэкапить? Есть подозрение что все эти тысячи файлов бэкапить будет тяжко, если не хранить их в базе данных…
  • Вопрос задан
  • 51278 просмотров
Решения вопроса 1
@edogs
На самом деле оба варианта по реализации настолько минимально отличаются, что хорошим советом будет «сделайте сейчас оба варианта, используйте сначала файлы, а когда файлов будет много померяете производительность».

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

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

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

Файлы при прочих равных однозначно лучше попадают в кэш, с другой стороны засирание кэша базой проще контроллировать.
Ответ написан
Пригласить эксперта
Ответы на вопрос 12
Единственное преимущество хранения файлов в БД, на которое нужно обратить внимание — это конкурентный доступ. То есть СУБД корректно обрабатывает одновременный доступ на изменение к одной и той же записи. Если конкурентный доступ маловероятен, то лучше использовать файлы.

Преимущество файлов:
— Бэкапить файлы не намного дольше, но восстанавливать можно по отдельным файлам, а не заливать весь дамп.
— Обращение к файлам и считывание быстрее, чем получение записи из БД (даже если используются сокеты).
— Кэширование файлов осуществляет автоматически ОС и сервер (можно использовать и опкэшер для контроля). А у СУБД кэширование больших файлов вызывает потерю производительности из-за вытеснения простых запросов из кэша.
— Количество файлов может быть очень большим без потери мощности сервера. У меня один раз хранилось около 12000 файлов в одной директории и ничего — сервер считывал без всяких задержек. Конечно вручную открыть эту папку было проблемно.
— Sphinx — свободно ищет по файлам.

Но при всех преимуществах файлов конкурентный доступ может испортить всю «малину», так что отталкивайтесь от него.
Ответ написан
Комментировать
seriyPS
@seriyPS
Когда у меня встала задача хранить 2млн HTML файлов, много чего перепробовал. Только у меня архив один раз формировался а потом в режиме read-only раздавался с помощью веб-сервера Tornado.

Остановился на SQLite + gzip. Т.е. создал таблицу с полями (name, blob) и каждый HTML сжимал в gzip.
В SQLite отключил синхронную запись для ускорения заполнения.
Успел попробовать bsd btree, bsd hash, gdbm, json-lines, csv ну и просто иерархия файлов на диске. Хотел попробовать tokyo cabinet, но не нашел драйверов для Python.
bsd btree в принципе сравнима с SQLite по скорости, но занимает больше места на диске и менее гибкое. json-lines занимает гораздо больше места, csv (и json тоже) нельзя упаковать в gzip и не поддерживает доступ по ключу.

Просто набор файлов на ФС — крайне неудобно для бэкапов и трудно с ними работать, например рекурсивное удаление занимает несколько часов.

gzip vs не gzip — однозначно gzip! Мало того, что «сжать в gzip и записать на диск» — быстрее чем просто «записать на диск», так ещё и место сэкономите.
Ответ написан
Комментировать
@Vampiro
— Странно, весь интернет хранит файлы на дисках и ничего. Если есть вариант, что MySQL будет хранить их не_на_диске, а где-то в другом месте, то, возможно, будет некий бонус. В остальном это лишние накладные расходы при каждом запросе.
— Никогда небыло проблемы с бекапом файлов. Есть туева хуча готовых утилит. И, кроме того, если вы планируете бекапить базу не методом бекапа её файлов, а поднимая слейв, то это еще больший гемор.
Ответ написан
@Vampiro
:) Думаете, если 4гб фильм затискать в мускуль, его потом будет быстрее/поще скачать? С чего бы это? В базе он будет занимать больше места. Соответственно, объем бекапа также будет больше. И скачать его будет сложнее.

В целом, поиск измененных файлов и инкрементный бекап на файлах реализуется проще, чем выборка из Mysql, архивация дампа и скачивание.
Ответ написан
serso
@serso
На самом деле разница небольшая.
Скажу лишь о плюсах базы:
1. Файлы хранящиеся в базе не подвержены заражению вирусами
2. Полный программный контроль над файлами (отдача файлов по привилегии и т.д.)
3. (Oracle) Полнотекстовый поиск (например, в xml)
Ответ написан
Если у вас html'ки, то есть текстовые фалйы, да еще если меняются не вильно отверсии к версии, то стоит рассмотреть хранение в файловой системе, а хранение старых версий в git.
Если же файлы меняются сильно, то я бы использовал ФС.

Но если файлов реально много и нужно распределять нагрузку на несколько узлов, то я бы подумал над использованием key value storage.

Но MySQL точно не для этого.
Ответ написан
Комментировать
Fahrain
@Fahrain Автор вопроса
А магическое число в 1000 файлов на папку чем-то обосновано?
Ответ написан
artyomst
@artyomst
как вариант — gridFS
Ответ написан
Комментировать
vsespb
@vsespb
Согласен что лучше не хранить их в базе.

Кроме того что перечислили хочу заметить, что:

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

— если у вас файлы на диске а метаинформация о них в БД, тут нужно быть осторожным, нет транзакционной целостности. (некоторые люди даже предпочитают не смешивать БД и диск и хранить все данные только на диске, но это каждый конкретный случай нужно рассматривать отдельно)
Ответ написан
Комментировать
Fahrain
@Fahrain Автор вопроса
Вообщем, всем спасибо, я все понял :) Пока сделаю на файлах, а потом по обстановке (количеству/нагрузке) уже решу стоит ли дальше заморачиваться или оставить как есть
Ответ написан
DMakeev
@DMakeev
«рекурсивное удаление занимает несколько часов» — по FTP удаляли?
Ответ написан
Все зависит от задач и от файловой системы на сервере. Так, в некоторых случаях ядро линукс для ext2 и ext3 имеет ограничение на количество директорий, а именно не более 32000 (''EXT2_LINK_MAX''' и '''EXT3_LINK_MAX''). Соотвественно, если Ваша система предназначена для использования на различных операционных системах и Вы не можете предвидеть на что ее будут устанавливать, советую хранить файлы в самой БД. Кроме того, это позволит избежать лишних проблем с мандатным доступом.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы