採用那種儲存最好?比如只需檢測這個資料庫中是否存在一個“9d97c57dfc685f9b10d8d1b944330c09”即可,返回true or false
回複內容:
採用那種儲存最好?比如只需檢測這個資料庫中是否存在一個“9d97c57dfc685f9b10d8d1b944330c09”即可,返回true or false
你的業務模型不清晰,沒法得到一個好的回答,我說幾個方法並說明優缺點吧
排序並順序儲存到硬碟,就32bit32bit32bit去順序儲存即可。搜尋採用最簡單的二分尋找(號稱90%的程式員面試的時候寫不出正確的二分尋找,不過你可以找個現成的)。時間複雜度O(logn),簡直飛快無比
優點:速度很快,磁碟空間壓縮到極限,無記憶體佔用
缺點:需要先做一次全排列(還好,一勞永逸)很難加入新的索引值(每次加入都要重排列,關鍵是需要重寫去dump磁碟)
結論:適合不再變動的資料
布隆過濾器。具體實現Google啊,比如這裡有個Python版的實現
優點:速度比較快,良好的插入效能
缺點:有錯誤率,雖然可控
結論:適合不是100%精確的需求,適合經常變動的資料
分區(類似於1樓的辦法)先雜湊,然後模數,比如5000,拆分成5000個子檔案。然後各子檔案分別排序。尋找時對key做hash並模數,找到對應的子檔案,然後再二分尋找。當然MD5一般可以認為是雜湊均勻的,那麼就不用雜湊,直接模數就好了。
優點:速度不錯且插入效能還可以(單次插入只用對單個分區進行插入排序)
缺點:貌似沒啥缺點,比較折衷
純Hash表,這個就不用說了吧,把所有資料讀到記憶體中,建立雜湊表(一億的話,雜湊表不大,也就幾個G)
優點:時間複雜度O(1),呵呵 插入複雜度O(1)
缺點:記憶體佔用。。。
結論:除了需要花錢,所有效能都是No1
最終結論:
- 來源資料永不變動,那就第一方案
- 不要求100%精確,那就第二方案
- 有錢買記憶體,就第四方案
- 普通人,第三方案
上面的幾種方法邏輯都非常簡單,實現起來很快的。有時間可以都實現下,測一測效能。
補充,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