文件存储散列算法
用户文件多的话,例如头像,存储到CDN的时候也要考虑目录平均散列
比较常用是按日期,例如 /2020/02/
但是缺点也非常明显,分布不均
或者直接按userId取模,例如 userId % 1000 分1000个目录来存放,只要userId是连续的,文件就必然是平均分布到这1000个目录
可是,数量很大的时候,一级目录下每个目录的文件数量或者一级目录就会非常多。
那么可以按二级目录来存放
function buildPath($id, $l1num, $l2num)
{
//(id %(二级目录数量*二级目录数量) / 二级目录数量 => 取整 一级目录
//(id %(二级目录数量*二级目录数量)% 二级目录数量 => 二级目录
$tmp = $id % ($l1num * $l2num);
$l1 = floor($tmp / $l2num);
$l2 = $tmp % $l2num;
return ['l1' => $l1, 'l2' => $l2];
}
为了方便演示我把一级目录和二级目录数量设置得比较小的值
就算是
$l1num = 10;
$l2num = 100;
$fileNum = 1000000;
每个目录就1000个文件,这样足够了:)
测试
$l1num = 2; //一级目录数量
$l2num = 5; //二级目录数量
$fileNum = 1000000; //文件数量
$dir = [];
for($i = 0; $i < $l1num; $i++) {
for ($j = 0; $j < $l2num; $j++) {
$dir[$i][$j] = 0;
}
}
for ($i = 1; $i <= $fileNum; $i++) {
$rs = $this->buildPath($i, $l1num, $l2num);
$dir[$rs['l1']][$rs['l2']]++;
}
print_r($dir);
Array
(
[0] => Array
(
[0] => 100000
[1] => 100000
[2] => 100000
[3] => 100000
[4] => 100000
)
[1] => Array
(
[0] => 100000
[1] => 100000
[2] => 100000
[3] => 100000
[4] => 100000
)
)
如果没有唯一id的话也可以使用文件md5后的hash截取部份字串来作来目录来存放,不过缺点就是目录数量就非常多,而且hash费cpu