在實際的軟體開發中,業務紛繁複雜,功能千變萬化,但是,萬變不離其宗,如果拋開這些業務和功能的外殼,其實它們的本質都可以抽象為「對資料的儲存和計算」。對應到資料結構和演算法中,那「儲存」需要的就是資料結構,「計算」需要的就是演算法。
對於儲存的需求,功能上無外乎增刪改查。這其實並不複雜。但是,一旦儲存的資料很多,那效能就成了這些系統要關注的重點,特別是在一些跟儲存相關的基礎系統(比如 mysql 資料庫、分布式檔案系統等)、中介軟體(比如訊息中介軟體 rocketmq 等)中。「如何節省儲存空間、如何提高資料增刪改查的執行效率」,這樣的問題就成了設計的重點。而這些系統的實現,都離不開乙個東西,那就是索引。不誇張地說,索引設計得好壞,直接決定了這些系統是否優秀。毫不誇張地說,索引設計得好壞,將直接決定這些系統是否優秀。
索引這個概念,可以模擬書籍的目錄來理解。如果沒有目錄,那當我們想要查詢書中某個知識點的時候,就要一頁一頁翻。但是,如果通過目錄,我們就可以快速定位到相關知識點的頁數,查詢的速度會有質的提高。如果用一句話來描述「索引」的作用,那就是:索引(index)是用來輔助查詢,用計算機專業術語就叫做 定址(addressing)。例如,陣列中的下標就是index。
理解了索引的概念後,接下來,我們就分析一下,在設計索引的過程中,一般需要考慮到的一些因素,換句話說就是,我們該如何定義清楚索引的需求呢?對於系統設計需求,我們一般可以從功能性需求和非功能性需求兩方面來分析,這個問題也不例外。
對於功能性需求需要考慮的點,大致概括成下面這幾點。實際上,不同的場景,不同的原始資料,對於索引的需求也會千差萬別。這裡也只是列舉了一些比較有共性的需求。
對於非功能性需求,我們著重考慮效能方面的需求。具體來說,效能方面的需求,我們主要考察時間和空間兩方面,也就是執行效率和儲存空間。在執行效率方面,我們希望通過索引,查詢資料的效率盡可能的高;在儲存空間方面,我們希望索引不要消耗太多的記憶體空間。
剛剛我們從很巨集觀的角度,總結了在索引設計的過程中,需要考慮的一些共性因素。現在,我們再來看,對於不同需求的索引結構,底層一般使用哪種資料結構。實際上,常用來構建索引的資料結構,就是我們之前講過的幾種支援對動態資料集合快速查詢、插入等操作的資料結構。比如,雜湊表、紅黑樹、跳表、b+ 樹。除此之外,位圖、布隆過濾器可以作為輔助索引,有序陣列可以用來對靜態資料構建索引。
二、引申
通過索引這個非常常用的技術方案,向你展示了雜湊表、紅黑樹、跳表、位圖、布隆過濾器、有序陣列這些資料結構的應用場景。實際上,架構設計離不開資料結構和演算法。要想成長為乙個優秀的業務架構師、基礎架構師,資料結構和演算法的根基一定要打穩。因為,那些看似很驚豔的架構設計思路,實際上,都是來自最常用的資料結構和演算法。
《資料結構與演算法之美》
王爭前google工程師
二十八 模組
模組 在電腦程式的開發過程中,隨著程式 越寫越多,在乙個檔案裡 就會越來越長,越來越不容易維護。為了編寫可維護的 我們把很多函式分組,分別放到不同的檔案裡,這樣,每個檔案包含的 就相對較少,很多程式語言都採用這種組織 的方式。在python中,乙個.py檔案就稱之為乙個模組 module 使用模組有...
Lua程式設計(二十八)
lua語言會在執行源 之前先對其進行預編譯。生成預編譯檔案 也被稱為二進位制檔案,binary chunk 的最簡單方式是,使用標準發行班中附帶的luac程式。luac o prog.lc prog.lua上述命令會建立檔案prog.lua的預編譯版本prog.lc。lua解析器會像執行普通lua ...
CUDA學習(二十八)
多處理器級別 在更低層次上,應用程式應該最大化多處理器內各個功能單元之間的並行執行 如 硬體多執行緒 中所述,gpu多處理器依賴於執行緒級並行性來最大限度地利用其功能單元。因此利用率與駐留經線的數量直接相關。在每個指令發布時間,乙個warp排程器選擇乙個準備好執行下乙個指令的warp 如果有的話 然...