如何使用哈希函数在文件系统中存储约400万个图像

时间:2014-05-21 15:35:17

标签: php image file storage

我想存储大约100万张图像,这些图像将被调整为4种不同的类型,因此会有大约400万张图像。我应该如何使用像md5这样的哈希函数来均匀而独特地在目录结构中分发图像?

3 个答案:

答案 0 :(得分:4)

正如其他人所说,多个文件名理论上可以散列为相同的值。除了哈希之外,通过保留原始文件名可以轻松解决这个问题。

在下文中,我假设您的一百万个输入文件具有唯一的文件名。

此示例还将原始及其缩略图放在同一目录中。这样可以轻松删除或查找文件。

首先,您需要一种方法将文件名映射到目录:

// $id = A unique identifier (a filename)
//       It could be useful to make this id the same for the original, 
//       as well as any thumbnails. Your image and variants will all
//       then end up in the same directory.

// $levels_deep = The number of directories deep you want to go.
//                Want more levels? Use a hashing method with a longer
//                output, such as sha1 (40 characters).

function getDir($id, $levels_deep = 32) {
    $file_hash   = md5($id);
    $dirname     = implode("/", str_split(
        substr($file_hash, 0, $levels_deep)
    ));
    return $dirname;
}

接下来,您需要写出文件:

function store($dirname, $filename) {
    // The `true` flag here will have `mkdir` create directories recursively.  
    if(!file_exists($dirname) && !mkdir($dirname, 0777, true))
        throw new Exception("Could not create directory " . $dirname);

    return file_put_contents(
        $dirname . "/" . $filename,
        "Contents of example file.\n"
    );
}

使用示例:

store(getDir("myfile.jpg", 4), "myfile.jpg");
store(getDir("myfile.jpg", 4), "myfile_large.jpg");
store(getDir("myfile.jpg", 4), "myfile_small.jpg");
store(getDir("myfile.jpg", 4), "myfile_thumb.jpg");
store(getDir("someOtherFile.jpg", 4), "someOtherFile.jpg");

这将在上述位置存储上述五个文件:

/d/0/6/a/myfile_large.jpg
/d/0/6/a/myfile_small.jpg
/d/0/6/a/myfile_thumb.jpg
/d/0/6/a/myfile.jpg
/1/4/4/d/someOtherFile.jpg

我没有研究过md5位的“随机性”,但应该分配得足够均匀。

答案 1 :(得分:0)

MD5用于检查文件的一致性。它可以是2个不同的图片具有相同的哈希值。所以最好不要使用哈希函数。你可以这样命名你的照片:

Timestamp_Number_1OfThe4Kinds
Example: 123456789_12_3.png

如何获取图片名称:

function getname($dir, $kindofpicture){
  i=0;
  do{
  $i++;
  $str=$dir.strval(time()).strval($i).$kindofvalue;
  }while(file_exists($str);
  return $str;
}

答案 2 :(得分:0)

MD5不会始终生成唯一值。如果可以将图像文件更改为增加的数字,则可以保存图像{number} _ {variant} .jpg,例如1_1.jpg,1_2.jpg,2_1.jpg等等。

为了让它看起来更随机一些,您可以将增加的数字从Base-10转换为Base-26。在这种情况下,图像82981_1.jpg将成为4IJF_1.jpg

如果使用数据库,则可以将原始文件名存储在数据库中,使用相应的记录ID重命名上面的文件。使用数据库还可以为您提供验证请求和存储统计信息的简便方法。