順序文件組織的缺點之一是必須經過訪問索引或使用二分法搜索來定位數據,這須要較多的I/O操做。基於散列技術的文件組織方式則不須要訪問索引結構,散列也提供了一種組織索引的方式。
在散列(hash)技術中,用桶(bucket)來表示能存儲一條或多條記錄的存儲單元。若是K表明全部搜索碼的集合,B表明全部bucket的集合,則散列函數h表示一個從K到B的映射函數。
插入搜索碼爲Ki的記錄時,經過散列函數計算h(Ki)得出bucket的地址,若是這個bucket還有空間,就將數據插入。
查詢Ki時,也是先經過h(Ki)得出bucket的地址,但bucket中每每有多條記錄,這時就須要進一步根據搜索碼在bucket內部搜索。
散列能夠有兩種用途,在散列文件組織中,經過散列函數直接定位記錄所在的磁盤塊;在散列索引組織中,把搜索碼和指針組織成一個散列文件結構。
a) 散列函數
合理地選擇散列函數很是重要,不然可能致使記錄被集中映射到少數幾個bucket的狀況。要求散列函數的分佈特性是均勻、隨機的,既每一個bucket被分配到的記錄數應該是相等的,並且分配結果與搜索碼自己的順序無關。
典型的散列函數是根據搜索碼的二進制值進行計算的,好比能夠計算二進制全部位的和,而後取模。一個結果良好設計的散列函數應不受記錄數量的影響,而具備穩定的搜索效率。
b) Bucket溢出的處理
若是記錄被映射到一個Bucket時Bucket以及沒有可用空間,就會發生溢出。溢出的緣由多是由於隨着記錄數的增加,沒有足夠的bucket;也多是由於散列函數設計不合理或者存在太多相同的搜索碼,致使記錄被集中映射到某些bucket,而一個bucket能容納的記錄是有限的,這種狀況稱爲桶偏斜(bucket skew)。
爲了應對bucket溢出,能夠在肯定bucket數量時留必定的餘量,但這會形成空間浪費;也可使用溢出桶(overflow bucket)來接收溢出記錄:一旦發生溢出,就新增一個溢出桶,以接收溢出記錄,溢出桶與原始桶構成鏈表(overflow chaining),因而查找數據時,要增長對是否存在溢出桶的探查,若是存在,則進一步在溢出桶中搜索。
這種靜態散列的缺點在於必須在設計階段肯定好bucket的數量,隨着記錄的數的增長或收縮,bucket數沒法跟隨變化,會形成溢出或空間浪費。
c) 散列索引
除了散列文件組織,還能夠用散列的方式組織索引。將散列函數做用於搜索碼以肯定對應的桶,而後將此搜索碼以及相應的指針存入。
學習資料:Database System Concepts, by Abraham Silberschatz, Henry F.Korth, S.Sudarshan函數