Один из возможных способов - вычислить подпись MD5 для файла (или идентификатор файла в базе данных), а затем построить / найти путь на основе этого.
Например, скажем, мы получаем подпись MD5, например "1ff8a7b5dc7a7d1f0ed65aaa29c04b1e"
Путь может выглядеть как "/ 1f / f" или "/ 1f / ff / 8a"
Причина в том, что вы не хотите, чтобы все файлы находились в одной папке, и вы хотите иметь возможность «разбивать» их на разные серверы, или на SAN, или на что-то другое в одинаковой степени .
Подпись MD5 представляет собой строку из 16 "шестнадцатеричных" символов. Так что наш пример "/ 1f / ff / 8a" дает нам 256 * 256 * 256 папок для хранения файлов. Этого должно быть достаточно для любого:)
Обновление, в связи с популярным спросом:
ПРИМЕЧАНИЕ - Я только что понял, что мы говорим именно о том, как это делает MediaWiki. Это не , теперь MediaWiki делает это, но другой способ, которым это могло бы быть сделано .
Под «подписью MD5» я имею в виду делать что-то вроде этого (примеры кода на Perl):
use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );
$ sig теперь состоит из 32 буквенно-цифровых символов: "1ff8a7b5dc7a7d1f0ed65aaa29c04b1e"
Затем создайте структуру папок следующим образом:
my $path = '/usr/local/media';
map { mkdir($path, 0666); $path .= "/$_" } $sig =~ m/^(..)(..)(..)/;
open my $ofh, '>', "$path/$sig"
or die "Cannot open '$path/$sig' for writing: $!";
print $ofh "File contents";
close($ofh);
Структура папок выглядит как
/
usr/
local/
media/
1f/
f8/
a7/
1ff8a7b5dc7a7d1f0ed65aaa29c04b1e