用户文件多的话,例如头像,存储到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

标签: 散列

添加新评论