Hash函式及其應用
本文部分內容摘自網路,參考資料連結會在文後給出,在此感謝原作者的分享。
計算理論中,沒有Hash函式的說法,只有單向函式的說法。所謂的單向函式,是一個複雜的定義,大家可以去看計算理論或者密碼學方面的資料。用“人類”的語言描述,單向函式就是:如果某個函式在給定輸入的時候,很容易計算出其結果來;而當給定結果的時候,很難計算出輸入來,這就是單向函式。各種加密函式都可以被認為是單向函式的逼近。Hash函式(或者稱為雜湊函式)也可以看成是單向函式的一個逼近。即它接近於滿足單向函式的定義。
Hash函式還有另外的含義。實際中的Hash函式是指把一個大範圍對映到一個小範圍。把大範圍對映到一個小範圍的目的往往是為了節省空間,使得資料容易儲存。除此以外,Hash函式往往應用於查詢上。所以,在考慮使用Hash函式之前,需要明白它的幾個限制:
- Hash的主要原理就是把大範圍對映到小範圍;所以,你輸入的實際值的個數必須和小範圍相當或者比它更小。不然衝突就會很多。
- 由於Hash逼近單向函式;所以,你可以用它來對資料進行加密。
- 不同的應用對Hash函式有著不同的要求;比如,用於加密的Hash函式主要考慮它和單項函式的差距,而用於查詢的Hash函式主要考慮它對映到小範圍的衝突率。
由於實現了Hash的資料結構支援隨機讀取(即直接定位,而不需要涉及各類查詢演算法),檢索效率非常高,成為了很多儲存引擎的首選,著名的有redis、memcache等,但是Hash的特性決定了一些應用場景下的不足:
- Hash 索引僅僅能滿足”=”,”IN”和”<=>”查詢,不能使用範圍查詢。
- Hash 索引無法被用來避免資料的排序操作。(即Hash函式並不會自排序,相對的如B樹,本身帶有排序資訊,在節點增刪改時按規則維護)
- Hash 索引不能利用部分索引鍵查詢。
稍加擴充套件的話,我們還可以將Hash應用在各種資料分散式技術中,這方面說的比較多的是“一致性雜湊演算法”,著名的開源分散式NoSQL資料庫系統Cassandra就應用了這一演算法。
對於資料檢索的低層面應用,主要是各類集合型別。在設計相關型別時,要考慮適當的Hash演算法,考慮因素主要是以下幾個方面:
- 計算Hash值所需的時間。
- Hash表長度。
- Hash值分佈情況。
- 資料的查詢頻率。
- Hash值衝突(重複)的概率。
衝突解決技術可分為兩大類:開雜湊法(又稱為鏈地址法)和閉雜湊法(又稱為開發地址法)。可假設實現Hash結構時,資料存放在預先用陣列實現的一片連續的地址空間,兩種衝突解決技術的區別在於發生衝突的元素是儲存在這片陣列的空間之外(開雜湊法,一般為附加連結串列形式)還是空間之內(閉雜湊法)。與閉雜湊法相比,開雜湊法有如下優缺點:
- 開雜湊法處理衝突無二次聚集現象,因此平均查詢時間較短。
- 由於開雜湊法中各連結串列上的節點空間是動態申請的,因此適合無法確定表長的情況。
- 指標需要額外空間,故當記錄規模較小時,閉雜湊法較為節省空間。
- 在.NET中,連結串列的各個元素分散於託管堆各處,這會給垃圾回收帶來壓力,影響程式效能。
在C#中,實現了Hash函式的集合類我知道的有兩個:System.Collections.Hashtable和System.Collections.Generic.Dictionary<TKey,TValue>,這兩者區別如下:
- Hashtable採用閉雜湊法來解決衝突,而Dictionary採用開雜湊法來解決衝突。
- Hashtable在空間不夠時,會自動擴容,在擴容時會重新計算所有元素的雜湊碼和雜湊地址,會消耗大量時間進行計算,Dictionary不存在這個問題(自然Dictionary在空間不夠時也要開闢新的空間,不過不需要重新計算和安排原有資料的雜湊值和雜湊地址,這方面內容可看Dictionary的原始碼便一清二楚了。
- Hashtable的執行緒安全包含幾個層次,預設可由多個讀取器執行緒或一個寫入執行緒使用;若要允許多執行緒寫入(在沒有執行緒讀取的情況下),則需要通過Synchronized方法返回的包裝完成;如果使用一個或多個讀取器以及一個或多個編寫器,則Synchronized包裝不提供執行緒安全的訪問,此時應使用SyncRoot鎖定集合。(MSDN說了這麼多,然後告訴我說Hashtable是執行緒安全的,難道不是在玩我?)Dictionary沒這麼複雜,只要Lock(SyncRoot)即可。
ps:關於NoSql,文中涉及了若干NoSql資料庫,博主就在此簡單說下對NoSql的一些個人見解。現在NoSql可謂風生水起,恰如當年web2.0、ajax剛興起的時候,其實都不是非常高深的技術,但卻能打破傳統,一領風騷好多年,所以說技術是其次,思想才是最重要的。ok扯遠了,NoSql和Sql儲存引擎差不多,總歸就那麼幾種,文中說到的Hash是一種,B數是一種,還有LSM樹之類的,頂多在區域性稍作改進以適應場景。它們真正的區別在於,NoSql不必非常顧忌資料庫正規化的約束,從而極大提高了讀寫速度和擴充套件能力,比如寫操作不care事務,在每秒寫幾萬幾十萬的資料量下,光這點就能甩Sql幾條街。可以說各類NoSql的爭奇鬥豔,其實都是以取消或部分取消資料庫正規化的約束為前提,看似很小的改變,能換來效能的巨大提升,當然這也伴隨著資料冗餘、安全性不高等Sqls深惡痛絕的問題。上帝總是公平的,任何事物都沒有絕對的好壞,就看你把它們用在什麼地方。
參考資料:
轉載請註明本文出處:http://www.cnblogs.com/newton/p/4561273.html
相關文章
- Hash 演算法及其應用演算法
- hash函式函式
- <Openssl下hash函式>函式
- ton函式函式hash的兩種形式函式
- hash函式的幾種函式
- 【分散式】CAP理論及其應用分散式
- php增量Hash函式的使用PHP函式
- gethostbyname函式和getservbyname函式的應用函式
- Vue函式式元件的應用Vue函式元件
- 函式柯里化和偏函式應用函式
- oracle中的幾個hash函式Oracle函式
- Excel函式應用教程:函式的引數(轉)Excel函式
- Java 函式式介面 lamada 應用Java函式
- Generator函式非同步應用函式非同步
- 函式計算——應用初探函式
- 函式進階應用3函式
- Ajax及其應用
- Excel函式應用教程:函式的輸入方法(轉)Excel函式
- Excel函式應用教程:函式與公式的概念(轉)Excel函式公式
- javascript高階函式的應用JavaScript函式
- 高階函式應用--currying函式
- pandas.DataFrame.groupby函式應用函式
- Python的sorted函式應用Python函式
- sqlserver拆分字串函式 及應用SQLServer字串函式
- 泛型及其應用泛型
- 閉包及其應用
- redis的incr和hash應用Redis
- 雜湊表(Hash)的應用
- 常見python資料型別及其相對應的函式Python資料型別函式
- 函數語言程式設計及其在react中的應用函數程式設計React
- day10-函式的應用函式
- 函式計算-HelloWorld應用開發函式
- 自定義UDF函式應用異常函式
- 應用呼叫驅動的ioctl函式函式
- JavaScript回撥函式應用淺析JavaScript函式
- 分析函式的應用(更新版)函式
- 四個PHP應用小函式 (轉)PHP函式
- PostgreSQL的generate_series函式應用SQL函式