Вот лучший метод, который я придумал до сих пор, и я хотел бы знать, есть ли еще лучший метод (я уверен, что есть!) Для хранения и извлечения миллионов изображений пользователей:
Чтобы уменьшить размеры каталогов и избежать необходимости делать какие-либо дополнительные вызовы в БД, я использую вложенные каталоги, которые рассчитываются на основе уникального идентификатора пользователя следующим образом:
$firstDir = './images'; $secondDir = floor($userID / 100000); $thirdDir = floor(substr($id, -5, 5) / 100); $fourthDir = $userID; $imgLocation = "$firstDir/$secondDir/$thirdDir/$fourthDir/1.jpg";
Идентификатор пользователя ( $userID
) варьируется от 1 до миллионов.
Поэтому, если у меня есть ID пользователя 7654321
, например, первая 7654321
этого пользователя будет сохранена в:
./images/76/543/7654321/1.jpg
Для ID пользователя 654321
:
./images/6/543/654321/1.jpg
Для ID пользователя 54321
это будет:
./images/0/543/54321/1.jpg
Для ID пользователя 4321
это будет:
./images/0/43/4321/1.jpg
Для ID пользователя 321
это будет:
./images/0/3/321/1.jpg
Для ID пользователя 21
это будет:
./images/0/0/21/1.jpg
Для ID пользователя 1
это будет:
./images/0/0/1/1.jpg
Это гарантирует, что с до 100 000 000 пользователей у меня никогда не будет каталога с более чем 1000 подкаталогами, поэтому он, кажется, сохраняет чистоту и эффективность.
Я сравнил этот метод с использованием следующего метода «хэш», который использует самый быстрый хеш-метод, доступный в PHP (crc32). Этот метод «хэш» вычисляет второй каталог как первые 3 символа в хэше идентификатора пользователя и третьего каталога в качестве следующего 3 символа, чтобы распределять файлы случайным образом, но равномерно следующим образом:
$hash = crc32($userID); $firstDir = './images'; $secondDir = substr($hash,0,3); $thirdDir = substr($hash,3,3); $fourthDir = $userID; $imgLocation = "$firstDir/$secondDir/$thirdDir/$fourthDir/1.jpg";
Однако этот метод «хэш» медленнее, чем метод, описанный выше, поэтому это не хорошо.
Затем я сделал еще один шаг и нашел еще более быстрый метод вычисления третьего каталога в моем первоначальном примере ( floor(substr($userID, -5, 5) / 100);
) следующим образом:
$thirdDir = floor(substr($userID, -5, 3));
Теперь это изменит, как / где хранятся первые 10 000 идентификаторов пользователя, в результате чего в некоторых третьих каталогах есть либо один пользовательский подкаталог, либо 111 вместо 100, но он имеет преимущество быть быстрее, так как нам не нужно делить на 100, поэтому я думаю, что это того стоит в долгосрочной перспективе.
Как только структура каталогов определена, вот как я планирую хранить фактические отдельные изображения: если пользователь загружает второй рис., Например, он будет находиться в том же каталоге, что и их первый рис, но он будет называться 2.jpg
, По умолчанию pic пользователя всегда будет просто 1.jpg
, поэтому, если они решат сделать свой второй рис по умолчанию, 2.jpg
будут переименованы в 1.jpg
и 1.jpg
будут переименованы в 2.jpg
.
И последнее, но не менее важное: если мне нужно было хранить несколько размеров одного и того же изображения, я бы сохранил их для идентификатора пользователя 1 (например):
1024px:
./images/0/0/1/1024/1.jpg ./images/0/0/1/1024/2.jpg
640px:
./images/0/0/1/640/1.jpg ./images/0/0/1/640/2.jpg
Вот и все.
Итак, есть ли недостатки в этом методе? Если да, не могли бы вы указать на них?
Есть ли лучший метод? Если да, не могли бы вы охарактеризовать это?
Прежде чем я приступлю к реализации этого, я хочу убедиться, что у меня есть лучший, быстрый и эффективный метод для хранения и получения изображений, чтобы мне не пришлось его снова менять.
Благодаря!
Не заботьтесь о небольших скоростных различиях при расчете пути, это не имеет значения. Важно то, насколько хорошо и равномерно распределены изображения в каталогах, насколько коротка создается путь, насколько сложно вывести соглашение об именах (позволяет заменить 1.jpg на 2.jpg .. вау, это работает ..) ,
Например, в вашем хэш-решении путь целиком основан на userid, который поместит все изображения, принадлежащие одному пользователю, в один и тот же каталог.
Используйте весь алфавит (нижний и верхний регистры, если ваш FS поддерживает его), а не только цифры. Проверьте, что делают другие программы, хорошее место, чтобы проверить имена хеширования directy – google chrome, mozilla, … Лучше иметь короткие имена каталогов. Быстрее искать, занимает меньше места в ваших html-документах.