2016-04-29 46 views
0

我有一些存儲在表誰上傳它和圖像的本地URL網址成員一同顯示的基於blockhash指紋:如何構建引用計算中選擇結果的MySQL查詢?

member varchar(8) 
fingerprint char(64) 
url  varchar(80) 

我試圖在做漢明距離計算這些散列來確定它們匹配的可能性(參考mysql hamming distance between two phash)。

鑑於我已經看到這樣做的最簡單的方法是使用MySql的bit_count函數來異或這兩個併產生一個總位數,我知道我必須將64個字符的散列分成4個塊,然後在將它們提供給bit_count之前,將它們轉換爲無符號整數。所以,我有一個查詢,做這樣的(從Linux命令行運行,因此參數變量):

select bit_count(cast(conv(substr('$1', 1, 16), 16, 10) as unsigned)^cast(conv(substr($2, 1, 16), 16, 10) as unsigned)) + 
bit_count(cast(conv(substr('$1', 17, 16), 16, 10) as unsigned)^cast(conv(substr('$2', 17, 16), 16, 10) as unsigned)) + 
bit_count(cast(conv(substr('$1', 33, 16), 16, 10) as unsigned)^cast(conv(substr('$2', 33, 16), 16, 10) as unsigned)) + 
bit_count(cast(conv(substr('$1', 49, 16), 16, 10) as unsigned)^cast(conv(substr('$2', 49, 16), 16, 10) as unsigned)); 

..和這將產生兩個指紋之間正確的結果。

但是,我需要一個查詢,它可以查找來自其他人的匹配指紋。基本上是:

select member, url 
from images 
where (Hamming Distance between <fingerprint> and (select hashes from member) < 10) 
    AND member != "<value>" 

我想我可能要創建一個存儲過程來確定的漢明距離,那麼也許限制結果我從整個數據庫進行檢查,像那些匹配前10個字符。但是有更好的方法嗎?

+0

在'images'和'member'之間使用連接。 – Barmar

回答

1

A hamming_distance存儲函數是個好主意。然後你可以在連接中使用它。

SELECT i1.member, i1.url 
FROM images AS i1 
JOIN images AS i2 ON i1.member != i2.member AND hamming_distance(i1.fingerprint, i2.fingerprint) < 10 
WHERE i2.member = @member_in_question 
1

該函數是個訣竅。它分割指紋並返回兩者之間的距離。然後,它是一個選擇的一個簡單的問題:

select member, url, fingerprint, hamming_dist(fingerprint, '$fingerprint') as distance from images where hash REGEXP '$find' && hamming_dist(hash, '$hash') < 8 && member != '$member';" 

正則表達式僅僅侷限於搜索到可能的匹配,它包括在指紋的第一個和最後一個字符。這樣做會將查詢時間從0.35秒降低到0.12秒。

感謝您的幫助!