@StynuBlizz

Как организовать хранение файлов на сервере?

Правильно ли я понимаю что для хранение файлов их нужно разбивать по папкам,если да то пойдет ли такая схема: допустим на сервер пользователь с Ником username заливает файл file.mp4, и я сохраняю этот файл по пути
u/us/use/user/usern/file.mp4 и такой путь формируется для каждого пользователя (вложенность каталогов равна 5),если будет 2 одинаковых названия файла у одного пользователя то просто добавляю к новому файлу номер (file1.mp4)?
Или это можно сделать как-то более правильнее?
  • Вопрос задан
  • 4350 просмотров
Решения вопроса 1
@marazmiki
Укротитель питонов
Правильно ли я понимаю что для хранение файлов их нужно разбивать по папкам,

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

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

А на боевых серверах использование хранилища в локальной файловой системе и вовсе нонсенс. Там эта проблема не стоит в принципе.

Сегментацию можно сделать для, скажем так, красоты. Или чтобы было понятно, кому принадлежит тот или иной файл. Но практическая польза от неё сомнительна. Вреда, впрочем, тоже нет :)

допустим на сервер пользователь с Ником username заливает файл file.mp4, и я сохраняю этот файл по пути u/us/use/user/usern/file.mp4 и такой путь формируется для каждого пользователя

Опять неправильно.

Во-первых, никогда, НИКОГДА не доверяйте данным, пришедшим от пользователя. Сохраняете загруженный файл – сгенерируйте имя сами. А оригинальное имя не возбраняется сохранить и в другом месте. Если понадобится дать возможность пользователю сохранить файл под оригинальным именем, это делается в несколько строк.

Во-вторых, Ваша сегментация слишком агрессивная. Если представить, что юзернейм может состоять только из строчных латинских букв и цифр (итого алфавит 26+10=36 символов), то такое хранилище сможет вместить 36 ^ (1 + 2 + 3 + 4 + 5) = 36^15 = 2.21 * 10^23 файлов без повторений. А что если юзернейм короче 5 символов? А что если он переименуется?

Помните "во-первых"? Так как нам нужно самим придумать имя файла, почему бы не воспользоваться либо UUID и сгенерировать уникальное (с высокой достоверностью) значение вида 28c5a6d8-f7b5-440f-aeaa-150e4fd0bebc, а его уже сегментировать? Например, два сегмента по два символа датут прикольные ссылки вида 28/c5/28c5a6d8-f7b5-440f-aeaa-150e4fd0bebc и возможность разместить 65 тысяч файлов так, чтобы они были по одной штуке в директории :)

Есть также вариант использовать не UUID, а посчитать контрольную сумму файла и взять её в качестве имени. Практическая ценность такого хеша, правда, тоже стремится к нулю :)

если будет 2 одинаковых названия файла у одного пользователя то просто добавляю к новому файлу номер (file1.mp4)

Если речь идёт о Джанге, то она сама так делает, это штатная функция хранилища.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@jkotkot
режим сарказма
Если у пользователя может быть много файлов, то будет жопа, а значит нужно создавать подпапки для файлов
Если будет много пользователей, то будет жопа, а значит нужно раскладывать пользователей по подпапкам.
Ответ написан
Комментировать
sim3x
@sim3x
Неважно, если не собираетесь ходить по директориям используюя mc или что-то подобное
Ответ написан
Комментировать
FeNUMe
@FeNUMe
Не стреляйте себе в ногу - послушайте Сергей и воспользуйтесь стандартными практиками:
используйте быстрый хеш-алгоритм для генерации имени файла - избежите проблем с дубликатами, с кодировками и недопустимыми символами в названии;
файлы раскидывайте по подпапкам на основе первых 2-3 символов хеша, а не по принадлежности к пользователю, тогда вложенности в 2 уровня вам будет с головой;
связь пользователь-файлы храните в базе, заодно и начальное название можно сохранить, если нужно;
если файлы мелкие(например, аватарки) то рассмотрите вариант хранения прямо в базе.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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