为了保持目录大小不变并避免对数据库进行任何其他调用,我使用的嵌套目录是根据用户的唯一ID计算的,如下所示:
$firstDir = './images'; $secondDir = floor($userID / 100000); $thirdDir = floor(substr($id,-5,5) / 100); $fourthDir = $userID; $imgLocation = "$firstDir/$secondDir/$thirdDir/$fourthDir/1.jpg";
用户ID($userID)的范围从1到数百万.
因此,如果我有用户ID 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个用户,我将永远不会有一个包含超过1,000个子目录的目录,因此它似乎可以保持清洁和高效.
我使用以下“哈希”方法对此方法进行基准测试,该方法使用PHP中可用的最快哈希方法(crc32).此“哈希”方法将第二个目录计算为用户ID哈希值中的前3个字符,将第三个目录计算为下一个3个字符,以便随机分布文件,但如下所示:
$hash = crc32($userID); $firstDir = './images'; $secondDir = substr($hash,3); $thirdDir = substr($hash,3,3); $fourthDir = $userID; $imgLocation = "$firstDir/$secondDir/$thirdDir/$fourthDir/1.jpg";
然后我更进了一步,发现了一个更快的方法来计算我原来的例子中的第三个目录(floor(substr($userID,5)/ 100);)如下:
$thirdDir = floor(substr($userID,3));
现在,这改变了存储前10,000个用户ID的方式/位置,使得一些第三个目录具有1个用户子目录或111而不是100,但它具有更快的优势,因为我们不必除以100,所以我认为从长远来看这是值得的.
一旦定义了目录结构,这就是我计划存储实际单个图像的方式:例如,如果用户上传第二张图片,它将与第一张图片位于同一目录中,但它将被命名为2.jpg .用户的默认pic总是只有1.jpg,所以如果他们决定将他们的第二张图片作为默认图片,那么2.jpg将被重命名为1.jpg,而1.jpg将被重命名为2.jpg.
最后但并非最不重要的是,如果我需要存储同一图像的多个大小,我会按如下方式存储它们用于用户ID 1(例如):
1,024像素:
./images/0/0/1/1024/1.jpg ./images/0/0/1/1024/2.jpg
640像素:
./images/0/0/1/640/1.jpg ./images/0/0/1/640/2.jpg
就是这样.
那么,这种方法有什么缺陷吗?如果是这样,你能指出来吗?
有更好的方法吗?如果是这样,你能描述一下吗?
在我开始实现这个之前,我想确保我有最好,最快,最有效的方法来存储和检索图像,这样我就不必再次更改它了.
谢谢!