1億個32位的md5的密碼值,怎樣查詢其中一個md5值是否存在效率最快?

來源:互聯網
上載者:User
採用那種儲存最好?比如只需檢測這個資料庫中是否存在一個“9d97c57dfc685f9b10d8d1b944330c09”即可,返回true or false

回複內容:

採用那種儲存最好?比如只需檢測這個資料庫中是否存在一個“9d97c57dfc685f9b10d8d1b944330c09”即可,返回true or false

你的業務模型不清晰,沒法得到一個好的回答,我說幾個方法並說明優缺點吧

  1. 排序並順序儲存到硬碟,就32bit32bit32bit去順序儲存即可。搜尋採用最簡單的二分尋找(號稱90%的程式員面試的時候寫不出正確的二分尋找,不過你可以找個現成的)。時間複雜度O(logn),簡直飛快無比
    優點:速度很快,磁碟空間壓縮到極限,無記憶體佔用
    缺點:需要先做一次全排列(還好,一勞永逸)很難加入新的索引值(每次加入都要重排列,關鍵是需要重寫去dump磁碟)
    結論:適合不再變動的資料

  2. 布隆過濾器。具體實現Google啊,比如這裡有個Python版的實現
    優點:速度比較快,良好的插入效能
    缺點:有錯誤率,雖然可控
    結論:適合不是100%精確的需求,適合經常變動的資料

  3. 分區(類似於1樓的辦法)先雜湊,然後模數,比如5000,拆分成5000個子檔案。然後各子檔案分別排序。尋找時對key做hash並模數,找到對應的子檔案,然後再二分尋找。當然MD5一般可以認為是雜湊均勻的,那麼就不用雜湊,直接模數就好了。
    優點:速度不錯且插入效能還可以(單次插入只用對單個分區進行插入排序)
    缺點:貌似沒啥缺點,比較折衷

  4. 純Hash表,這個就不用說了吧,把所有資料讀到記憶體中,建立雜湊表(一億的話,雜湊表不大,也就幾個G)
    優點:時間複雜度O(1),呵呵 插入複雜度O(1)
    缺點:記憶體佔用。。。
    結論:除了需要花錢,所有效能都是No1

最終結論:

  1. 來源資料永不變動,那就第一方案
  2. 不要求100%精確,那就第二方案
  3. 有錢買記憶體,就第四方案
  4. 普通人,第三方案

上面的幾種方法邏輯都非常簡單,實現起來很快的。有時間可以都實現下,測一測效能。

補充,Hash表到底有多快。。

產生1000w 隨機字串(單行長度32位元組)

$ head -1 1000wbCxshZTroH6OukITgLsCccK9SlBd7CHL

取後100條字串(grep的最壞情況)

$ tail -100 1000w> q100$ time (cat q100 | while read line;do grep -Fx $line 1000w >/dev/null;done) 6.87s user 7.36s system 99% cpu 14.322 total

可以看到grep最壞效能是 7req/s,時間複雜度是O(n)

使用awk評估hash表的效能(awk的dict是hash表實現的)

$ time awk 'ARGIND==1{a[$0]}' 1000w14.24s user 0.61s system 99% cpu 14.861 total 

可以看到雜湊表的載入時間是15s,注意寫成服務的話載入一次就夠了,所以載入時間是不算的

查詢效能,我們直接全量查詢

$ time awk 'ARGIND==1{a[$0]} ARGIND>1&&($0 in a){print $0}' 1000w 1000w >/dev/null27.88s user 0.73s system 99% cpu 28.734 total

hash表的效能是 10000000/(28.734 - 14.861) = 720824req/s 是grep的10w倍,時間複雜度是O(1)

本人演算法比較差,給一個我的簡單思路
用過git的都知道,git的object對象名就是一個雜湊值(sha-1)的後38位,
git的objects目錄裡的子目錄,是objects對象的雜湊值的前兩位
尋找一個objects對象,先根據前兩位找到對應目錄,再去目錄下找具體檔案
如下是git objects目錄下的部分顯示:

00  06  0c  12  18  1e  24  2a  30  36  3c  42  48  4e  54  5a  60  66  6c  72  78  

這樣就能保證資料被比較均勻的分散在不同的目錄裡

同理,你可以在你的資料庫中建立一些這樣的表
比如 md5_3e,md5_06,...
當你想尋找 3eabecb5ff177ebadd305fe52e278d92df3754是否存在
首先看存在表md5_3e嗎,如果存在,則繼續在md5_3e裡查看是否存在abecb5ff177ebadd305fe52e278d92df3754 這樣的值

此方案中,每個表大概儲存資料為30多萬,給欄位加上索引,查詢速度肯定飛快的

這是我的思路,應該也算最簡單的能實現需求的方法

樓主可以去研究下bit-map的相關東西,對你的問題很有協助哦。

可以試下布隆過濾器,bloom filter,在判斷一個元素是否屬於某個集合時,有可能把不屬於這個集合的元素誤認為屬於這個集合,但不會把屬於這個集合的元素誤認為不屬於這個集合,不適合零錯誤的情境

可以試試基於二分法的存儲結構。

比如 B-樹等

詳見 http://blog.csdn.net/v_july_v/article/details/6530142

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.