以下是我目前想到的最佳方法,希望知道是否有更好的方法(肯定有!)来存储和获取数百万个用户图像:
为了保持目录大小并避免进行任何额外的数据库调用,我使用基于用户唯一ID计算的嵌套目录,如下所示:
这样可以确保即使有1亿用户,也不会出现超过1000个子目录的情况,因此似乎可以保持目录的整洁和高效。
我将这种方法与使用以下“哈希”方法进行了基准测试,该方法使用PHP中最快的哈希方法(crc32)。该“哈希”方法计算第二个目录为用户ID哈希的前3个字符,将第三个目录计算为接下来的3个字符,以便按顺序随机但均匀地分配文件,如下所示:
然而,这种“哈希”方法比我之前描述的方法慢,因此并不好。接着,我走了一步 further,找到了一个更快的方法来计算我原始例子中的第三个目录(
现在,这改变了前10000个用户ID存储的方式/位置,使一些第三方目录只有1个用户子目录或111个用户子目录,而不是100个,但它具有更快的速度,因为我们不必除以100,所以我认为从长远来看这是值得的。
为了保持目录大小并避免进行任何额外的数据库调用,我使用基于用户唯一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
这样可以确保即使有1亿用户,也不会出现超过1000个子目录的情况,因此似乎可以保持目录的整洁和高效。
我将这种方法与使用以下“哈希”方法进行了基准测试,该方法使用PHP中最快的哈希方法(crc32)。该“哈希”方法计算第二个目录为用户ID哈希的前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";
然而,这种“哈希”方法比我之前描述的方法慢,因此并不好。接着,我走了一步 further,找到了一个更快的方法来计算我原始例子中的第三个目录(
floor(substr($userID, -5, 5) / 100);
),具体方法如下:$thirdDir = floor(substr($userID, -5, 3));
现在,这改变了前10000个用户ID存储的方式/位置,使一些第三方目录只有1个用户子目录或111个用户子目录,而不是100个,但它具有更快的速度,因为我们不必除以100,所以我认为从长远来看这是值得的。
一旦目录结构被定义,以下是我计划如何存储实际的单个图像:例如,如果用户上传第二张图片,它将放置在与他们的第一张图片相同的目录中,但它的名称将是2.jpg
。 用户的默认图片总是1.jpg
,因此如果他们决定将第二张图片设置为默认图片,则2.jpg
将重命名为1.jpg
,并且1.jpg
将被重命名为2.jpg
。
最后但并非最不重要的是,如果我需要存储同一图像的多个尺寸,则会按以下方式为用户ID 1进行存储:
1024px:
./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
就是这样。
那么,这种方法有什么缺陷吗?如果有的话,请指出来。
有没有更好的方法?如果有的话,请描述一下。
在我开始实现它之前,我想确保我拥有最佳、最快和最有效的存储和检索图像的方法,这样我就不必再次更改它。
谢谢!
memcached
,并依赖于这样一个假设:95%的用户大部分时间都想看到同样的5%的图片。 - Damon