PHP/SQL-比较大量图像

PHP/SQL-比较大量图像,php,sql,image,compare,Php,Sql,Image,Compare,我创建了一个脚本,该脚本将大量图像放入数据库。我只想杂志唯一的图像,所以我应该检查每次,如果现在得到的图像存在于我的数据库。这就是我的问题——当我的数据库中有大约1000000条记录时,我如何在短时间内做到这一点 我的想法是在每张图像上使用strlen(): $image = file_get_contents('http://server.com/imageX.jpg'); $counter = strlen($image); // $counter => for example: 10

我创建了一个脚本,该脚本将大量图像放入数据库。我只想杂志唯一的图像,所以我应该检查每次,如果现在得到的图像存在于我的数据库。这就是我的问题——当我的数据库中有大约1000000条记录时,我如何在短时间内做到这一点

我的想法是在每张图像上使用strlen():

$image = file_get_contents('http://server.com/imageX.jpg');
$counter = strlen($image);
// $counter => for example: 105188 
然后将此号码保存在数据库中,并使用INSERT IGNORE INTO:

INSERT IGNORE INTO `database` (`unique_counter`, `img_url`, `img_name`) VALUES (105188, 'http://server.com/imageX.jpg', 'imageX.jpg')
如果要添加此图像,则一切正常。但我认为这个想法适用于大约100张图片。当我有1000000张或更多的图片,并且所有这些图片都有相似的大小(宽度和高度),我的想法是,当图片不一样时,计数器也可以是相同的

你能帮忙吗?如何在很短的时间内比较数据库中的许多图像


谢谢。

您应该为这些图像创建一个哈希,然后将它们存储到数据库中

您可以使用
$hash=md5\u文件($file\u路径)
获取较小文件的哈希值

如果你有非常大的图像,你可以得到散列而不影响内存限制

function get_hash($file_path, $limit = 0, $offset = 0) {

    if (filesize($file_path) < 15728640) { //get hash for less than 15MB images
        // md5_file is always faster if we don't chunk the file
        $hash = md5_file($file_path);

        return $hash !== false ? $hash : null;
    }

    $ctx = hash_init('md5');

    if (!$ctx) {
        // Fail to initialize file hashing
        return null;
    }

    $limit = filesize($file_path) - $offset;

    $handle = @fopen($file_path, "rb");
    if ($handle === false) {
        // Failed opening file, cleanup hash context
        hash_final($ctx);

        return null;
    }

    fseek($handle, $offset);

    while ($limit > 0) {
        // Limit chunk size to either our remaining chunk or max chunk size
        $chunkSize = $limit < 131072 ? $limit : 131072;
        $limit -= $chunkSize;

        $chunk = fread($handle, $chunkSize);
        hash_update($ctx, $chunk);
    }

    fclose($handle);

    return hash_final($ctx);
}
函数get\u hash($file\u path,$limit=0,$offset=0){ 如果(filesize($file_path)<15728640){//获取小于15MB图像的哈希值 //如果我们不分块文件,md5_文件总是更快 $hash=md5\u文件($file\u路径); 返回$hash!==false?$hash:null; } $ctx=hash_init('md5'); 如果(!$ctx){ //无法初始化文件哈希 返回null; } $limit=filesize($file\u path)-$offset; $handle=@fopen($file_path,“rb”); 如果($handle==false){ //打开文件失败,清除哈希上下文 最终价格($ctx); 返回null; } fseek($handle,$offset); 而($limit>0){ //将区块大小限制为剩余区块或最大区块大小 $chunkSize=$limit<131072?$limit:131072; $limit-=$chunkSize; $chunk=fread($handle,$chunkSize); hash_更新($ctx,$chunk); } fclose($handle); 返回hash_final($ctx); }
您应该为这些图像创建一个哈希,然后将它们存储到数据库中

您可以使用
$hash=md5\u文件($file\u路径)
获取较小文件的哈希值

如果你有非常大的图像,你可以得到散列而不影响内存限制

function get_hash($file_path, $limit = 0, $offset = 0) {

    if (filesize($file_path) < 15728640) { //get hash for less than 15MB images
        // md5_file is always faster if we don't chunk the file
        $hash = md5_file($file_path);

        return $hash !== false ? $hash : null;
    }

    $ctx = hash_init('md5');

    if (!$ctx) {
        // Fail to initialize file hashing
        return null;
    }

    $limit = filesize($file_path) - $offset;

    $handle = @fopen($file_path, "rb");
    if ($handle === false) {
        // Failed opening file, cleanup hash context
        hash_final($ctx);

        return null;
    }

    fseek($handle, $offset);

    while ($limit > 0) {
        // Limit chunk size to either our remaining chunk or max chunk size
        $chunkSize = $limit < 131072 ? $limit : 131072;
        $limit -= $chunkSize;

        $chunk = fread($handle, $chunkSize);
        hash_update($ctx, $chunk);
    }

    fclose($handle);

    return hash_final($ctx);
}
函数get\u hash($file\u path,$limit=0,$offset=0){ 如果(filesize($file_path)<15728640){//获取小于15MB图像的哈希值 //如果我们不分块文件,md5_文件总是更快 $hash=md5\u文件($file\u路径); 返回$hash!==false?$hash:null; } $ctx=hash_init('md5'); 如果(!$ctx){ //无法初始化文件哈希 返回null; } $limit=filesize($file\u path)-$offset; $handle=@fopen($file_path,“rb”); 如果($handle==false){ //打开文件失败,清除哈希上下文 最终价格($ctx); 返回null; } fseek($handle,$offset); 而($limit>0){ //将区块大小限制为剩余区块或最大区块大小 $chunkSize=$limit<131072?$limit:131072; $limit-=$chunkSize; $chunk=fread($handle,$chunkSize); hash_更新($ctx,$chunk); } fclose($handle); 返回hash_final($ctx); }
不要使用filesize,而是用md5/sha1对其进行散列,不仅URL是唯一的。@LawrenceCherone,而且它仍然是我第一次发布的想法-获取图像,对其进行散列,然后计数-我想当我有1.000.000多个图像时,这种方法不适合我,因为它可能会拒绝不在我的数据库中但具有相同长值的图像。使用say md5哈希将有2^32的冲突机会,文件大小不会。是否要检测二进制文件中的唯一性?这只有通过读取两个文件并进行比较才能实现。但是,您可以选择快捷方式。文件大小是一种只需比较相同大小的文件的想法。散列码是另一种。文件名必须匹配吗?存档日期?进出口银行数据?归结起来就是:存储的数据越多,必须比较的文件就越少。如果存储两个字节的哈希代码,则只有2^16个不同的值;如果存储20个字节的哈希代码,则有2^160个值。因此,碰撞要少得多,但仍然需要时不时地比较这些文件。是的,正如@lawrencerone所提到的<代码>md5长度为32。因此,您不必担心长度。不要使用文件大小,而是使用md5/sha1对其进行哈希,不仅URL是唯一的。@LawrenceCherone,而且它仍然是我第一次发布的想法-获取图像,对其进行哈希,然后计数-我想当我有1.000.000+个图像时,这种方法不适合我,因为它可能会拒绝不在我的数据库中但具有相同长值的图像。使用say md5哈希将有2^32的冲突机会,文件大小不会。是否要检测二进制文件中的唯一性?这只有通过读取两个文件并进行比较才能实现。但是,您可以选择快捷方式。文件大小是一种只需比较相同大小的文件的想法。散列码是另一种。文件名必须匹配吗?存档日期?进出口银行数据?归结起来就是:存储的数据越多,必须比较的文件就越少。如果存储两个字节的哈希代码,则只有2^16个不同的值;如果存储20个字节的哈希代码,则有2^160个值。因此,碰撞要少得多,但仍然需要时不时地比较这些文件。是的,正如@lawrencerone所提到的<代码>md5长度为32。所以你不需要担心长度。所以我应该从url获取图像代码,然后对其进行散列(md5、sha等),并将该散列保存在我的数据库中。那就只比较这个散列,对吗?这对我来说是最好的主意?没错,效果很好。我们正在运行一个应用程序,它对数百万个文件和图像执行相同的操作。我应该从url获取图像代码,然后对其进行哈希(md5、sha等),并将此哈希保存在我的数据库中。然后只比较这个散列,