Страницы

Поиск по вопросам

вторник, 25 февраля 2020 г.

Как правильно хранить файлы на веб-сервере?

#php #файлы #хранение_данных


Я бы хотел задать кое-какие вопросы о построении каталогов и хранении в них файлов
(картинок, к примеру).

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

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

Многие советуют делать это след. образом:
Вкратце опишу, генерируем название файла с помощью md5 хэша.
Затем, берем первые 2 символа из название и создаём папку и туда помещаем все файлы,
которые начинаются на одни и те же символы, подобным образом мы можем создать 256 папок
в которые, к примеру, мы можем поместить по 1000 файлов. Разумеется, можно делать вложенные
уровни из 3 и 4 символа из 5 и 6 и тд.

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

Мой вариант, который пришел в голову (Думаю, я не первый):
Создаем папку с числом текущего года, к примеру, затем текущего месяца и в папке
с числом месяца создаем папку с днем месяца и в ней создаем папку с названием 1 и забиваем
её до тех пор пока в ней не будет 1000 файлов, затем создаем папку с числом 2 и забиваем
её, ну и в таком же духе и дальше.

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

Для наглядности:
2015/04/15/1

Забиваем папку с названием 1 до 1000 файлов, затем создаем папку с названием 2, после
3 и так до 1000

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

Какие у вас мысли по этому поводу? Какую структуру хранения файлов используете вы?
И чем она хороша? Приемлема ли та структура которую описал я, с вашей точки зрения?
Что скажете по поводу производительности?
    


Ответы

Ответ 1



Ответ достаточно общий, без всякой привязки к PHP. Если требуется поиск файлов по имени, то я бы попробовал все же сделать структуру, основанную на MD5 (или другой хэш-функции) в 16-ричном виде (для MD5 все имя это 32 символа от 0 до f), только не с жесткой организацией уровней каталогов, а с динамической. Имена каталогов задаются, например, тройками символов. Соответственно, каталог может содержать до 4096 других каталогов. Для начала начинаем помещать в каталог сами файлы (с MD5-именем). Можно еще завести там служебный файл для отображения хэша в имя (может пригодиться, если захотите узнать реальные имена хранимых файлов) и синонимов (вдруг такое произойдет). Впрочем, структура такого файла -- это отдельный вопрос. Когда в каталоге соберется 4096 файлов мы проводим реорганизацию. Делаем по первой тройке символов имен файлов каталоги и перемещаем файлы в них. Надеюсь, далее очевидно.

Ответ 2



что будет, если одна из папок забьется гораздо раньше чем другие? Странный вопрос. С какой стати одна должна забиться раньше? Это ведь рандомный хэш, а не пользовательское имя файла на IMG_. Ну да, хэш надо генерировать с умом. Но это проблема генерации хэша, а не самого принципа. То есть я не понимаю логику, стоящую за этим доводом. Это все равно что решать, чем есть борщ, и отказаться от ложки только потому, что кто-то, возможно, её в руках не умеет держать. Ну так надо одного криворукого учить, а не всем хлебать через край. Чем система проще, тем она лучше работает. В простой системе нечему ломаться. Если изначально задать алгоритм, который не будет требовать никаких пересчетов и реорганизаций, то он и будет работать без необходимости каждый раз(!) файлы в папке пересчитывать. Самый оптимальный вариант - это md5() от содержимого. Обеспечит не только вполне случайное распределение, но и сэкономит место в случае дублей (только при удалении надо быть внимательным и смотреть нет ли других записей, ссылающихся на тот же файл). Плюс можно перевести хэш из 16-ричной системы в 36-ричную, задействовав все буквы алфавита, а не только первые 6. Что сократит длину хэша и одновременно увеличит количество вариантов для разбивки, уменьшая необходимую глубину папок.

Ответ 3



Однажды я делал фотохостинг, и я делал следующим образом: По задумке сайта, для каждой картинки есть ссылка в формате example.com/vnjum. Как в сокращалке ссылок. Тогда картинка сохраняется в папку example.com/images/v/n/j/u/m/image.jpg Тогда и из ссылки на сайт можно получить ссылку на сам файл и наоборот) Вот вам еще один метод. В документа будет два идентификатора - время загрузки и случайное число от 100 000 до 999 999. Для примера, время будет 1540670259710 (это UNIX-формат), а случайное число - 125793. Переводим дату в 36-ричную систему (в JavaScript - .toString(36)), получаем jnrvakn2. Делим на куски по 1-2-2-3 символа. Получаем j-nr-va-kn2. Далее берем наше случайное число - 125793. В 36-ричной системе это будет 2p29. Получаем адрес /j/nr/va/kn2/2p29/filename.jpg

Комментариев нет:

Отправить комментарий