怎麼從海量資料中快速查詢某個資料 索引

2021-10-10 22:40:40 字數 1788 閱讀 8943

mysql 底層依賴的是 b+ 樹這種資料結構。

那類似 redis 這樣的 key-value 資料庫中的索引,又是怎麼實現的呢?底層依賴的又是什麼資料結構呢?

索引這種常用的技術解決思路,底層往往會依賴哪些資料結構。同時,通過索引這個應用場景,你學過過或者知道幾種支援動態集合的資料結構呢?

在實際的軟體開發中,業務紛繁複雜,功能千變萬化,但是,萬變不離其宗。如果拋開這些業務和功能的外殼,其實它們的本質都可以抽象為「對資料的儲存和計算」。對應到資料結構和演算法中,那「儲存」需要的就是資料結構,「計算」需要的就是演算法。

對於儲存的需求,功能上無外乎增刪改查。這其實並不複雜。但是,一旦儲存的資料很多,那效能就成了這些系統要關注的重點,特別是在一些跟儲存相關的基礎系統(比如 mysql 資料庫、分布式檔案系統等)、中介軟體(比如訊息中介軟體 rocketmq 等)中。

「如何節省儲存空間、如何提高資料增刪改查的執行效率」,這樣的問題就成了設計的重點。而這些系統的實現,都離不開乙個東西,那就是索引。不誇張地說,索引設計得好壞,直接決定了這些系統是否優秀。

索引這個概念,非常好理解。面試很多人會說模擬書籍的目錄來理解(面試不要在這麼說了,太low了,說是資料結構就行了)。

索引的概念不難理解,但在設計索引的過程中,需要考慮到的一些因素,對於系統設計需求,一般可以從功能性需求和非功能性需求兩方面來分析。

對於功能性需求需要考慮的點,大致概括成下面這幾點。

實際上,不同的場景,不同的原始資料,對於索引的需求也會千差萬別。這裡只列舉了一些比較有共性的需求。

再來看索引設計的非功能性需求。

從很巨集觀的角度,總結了在索引設計的過程中,需要考慮的一些共性因素。現在,對於不同需求的索引結構,底層一般使用哪種資料結構。

實際上,常用來構建索引的資料結構,幾種支援動態資料集合的資料結構。比如,雜湊表、紅黑樹、跳表、b+ 樹。除此之外,位圖、布隆過濾器可以作為輔助索引,有序陣列可以用來對靜態資料構建索引。

雜湊表增刪改查操作的效能非常好,時間複雜度是 o(1)。一些鍵值資料庫,比如 redis、memcache,就是使用雜湊表來構建索引的。這類索引,一般都構建在記憶體中。

紅黑樹作為一種常用的平衡二叉查詢樹,資料插入、刪除、查詢的時間複雜度是

o(logn)

,也非常適合用來構建記憶體索引。

ext

檔案系統中,對磁碟塊的索引,用的就是紅黑樹。

b+ 樹比起紅黑樹來說,更加適合構建儲存在磁碟中的索引。

b+ 樹是乙個多叉樹,所以,對相同個數的資料構建索引,

b+ 樹的高度要低於紅黑樹。當借助索引查詢資料的時候,讀取

b+ 樹索引,需要的磁碟

io 次數會更少。所以,大部分關係型資料庫的索引,比如

mysql

、oracle

,都是用

b+ 樹來實現的。

跳表也支援快速新增、刪除、查詢資料。而且通過靈活調整索引結點個數和資料個數之間的比例,可以很好地平衡索引對記憶體的消耗及其查詢效率。

redis

中的有序集合,就是用跳表來構建的。

除了雜湊表、紅黑樹、

b+ 樹、跳表之外,點陣圖和布隆過濾器這兩個資料結構,也可以用於索引中,輔助儲存在磁碟中的索引,加速資料查詢的效率。

布隆過濾器有一定的判錯率。但是可以規避它的短處,發揮它的長處。儘管對於判定存在的資料,有可能並不存在,但是對於判定不存在的資料,那肯定就不存在。而且,布隆過濾器還有乙個更大的特點,那就是記憶體占用非常少。可以針對資料,構建乙個布隆過濾器,並且儲存在記憶體中。當要查詢資料的時候,可以先通過布隆過濾器,判定是否存在。如果通過布隆過濾器判定資料不存在,那就沒有必要讀取磁碟中的索引了。對於資料不存在的情況,資料查詢就更加快速了。

Sphinx 實現海量資料的快速查詢

執行測試 cd usr local sphinx etc cp sphinx.conf dist sphinx.conf vi sphinx.confcd usr local sphinx etc 進入sphinx的配置檔案目錄 cp sphinx.conf dist sphinx.conf 新建s...

從海量資料中查詢乙個數

題目 給出40億個不重複的unsigned int的整數,沒排過序,再給乙個指定的數,判斷這個數是否在那40億個數 中 存在?方案一 申請512mb的記憶體,利用位圖,乙個bit代表乙個unsigned int的值,讀入這40億個數,設定相應的位,存在的設定為1,不存在的設定為0,然後我們只需要o ...

從資料庫中快速查詢對應資訊

昨天我需要修改介面dto的屬性與資料庫中的字段匹配,我採用的是直接查詢注釋的方式,大部分寫了注釋的都能輕鬆找到。其他的需要通過理解表與表之間的關係才能找到對應字段。比如我需要查詢 檢測人員名稱 屬性,就需要考慮通過程式入口的那個表的 員工id 欄位來查詢 員工名稱 這時候用查注釋的方式就不管用了,需...