python3的pyqt5 qtablewidget按數據大小排列_InnoDB為什么要選擇B+樹來存儲數據?


關于InnoDB索引,我們可能知道InnDB索引是用B+樹實現的,而B+樹就是一種能優化查詢速度的數據結構。但我們又沒想過這樣一個問題,能優化查詢速度的數據結構有很多,為什么InnoDB要采用B+樹?

常見優化查詢速度數據結構

哈希表

哈希表是一種以鍵 - 值(key-value)存儲數據的結構,我們只要輸入待查找的鍵即 key,就可以找到其對應的值即 Value。哈希的思路很簡單,把值放在數組里,用一個哈希函數把 key 換算成一個確定的位置,然后把 value 放在數組的這個位置。

不可避免地,多個 key 值經過哈希函數的換算,會出現同一個值的情況。處理這種情況的一種方法是,拉出一個鏈表。

假設現在維護著一個身份證信息和姓名的表,需要根據身份證號查找對應的名字,這時對應的哈希索引的示意圖如下所示:

645fdaa0aa6f828d79aeb5650fc297b6.png

圖中,User2 和 User4 根據身份證號算出來的值都是 N,但沒關系,后面還跟了一個鏈表。假設,這時候你要查 IDcardn2 對應的名字是什么,處理步驟就是:首先,將 IDcardn2 通過哈希函數算出 N;然后,按順序遍歷,找到 User2。

需要注意的是,圖中四個 IDcardn 的值并不是遞增的,這樣做的好處是增加新的 User 時速度會很快,只需要往后追加。但缺點是,因為不是有序的,所以哈希索引做區間查詢的速度是很慢的。

可以設想下,如果現在要找身份證號在[IDcardX, IDcardY]這個區間的所有用戶,就必須全部掃描一遍了。

所以,哈希表這種結構適用于只有等值查詢的場景,比如 Memcached 及其他一些 NoSQL 引擎。

有序數組

有序數組在等值查詢和范圍查詢場景中的性能就都非常優秀。還是上面這個根據身份證號查名字的例子,如果我們使用有序數組來實現的話,示意圖如下所示:

73f2b50ff703969b76ef4f1033089b78.png

這里我們假設身份證號沒有重復,這個數組就是按照身份證號遞增的順序保存的。這時候如果你要查 IDcardn2 對應的名字,用二分法就可以快速得到,這個時間復雜度是 O(log(N))。

同時很顯然,這個索引結構支持范圍查詢。要查身份證號在[IDcardX, IDcardY]區間的 User,可以先用二分法找到 IDcardX(如果不存在 IDcardX,就找到大于 IDcardX 的第一個 User),然后向右遍歷,直到查到第一個大于 IDcardY 的身份證號,退出循環。

如果僅僅看查詢效率,有序數組就是最好的數據結構了。但是,在需要更新數據的時候就麻煩了,往中間插入一個記錄就必須得挪動后面所有的記錄,成本太高。

所以,有序數組索引只適用于靜態存儲引擎,比如要保存的是 2017 年某個城市的所有人口信息,這類不會再修改的數據。

二叉搜索樹

上面根據身份證號查名字的例子,如果我們用二叉搜索樹來實現的話,示意圖如下所示:

094d990aa71d86b3a099e541ee7a9da2.png

二叉搜索樹的特點是:每個節點的左兒子小于父節點,父節點又小于右兒子。這樣如果你要查 IDcardn2 的話,按照圖中的搜索順序就是按照 UserA -> UserC -> UserF -> User2 這個路徑得到。這個時間復雜度是 O(log(N))。

當然為了維持 O(log(N)) 的查詢復雜度,就需要保持這棵樹是平衡二叉樹。為了做這個保證,更新的時間復雜度也是 O(log(N))。

樹可以有二叉,也可以有多叉。多叉樹就是每個節點有多個兒子,兒子之間的大小保證從左到右遞增。二叉樹是搜索效率最高的,但是實際上大多數的數據庫存儲卻并不使用二叉樹。其原因是,索引不止存在內存中,還要寫到磁盤上。

可以想象一下一棵 100 萬節點的平衡二叉樹,樹高 20。一次查詢可能需要訪問 20 個數據塊。在機械硬盤時代,從磁盤隨機讀一個數據塊需要 10 ms 左右的尋址時間。也就是說,對于一個 100 萬行的表,如果使用二叉樹來存儲,單獨訪問一個行可能需要 20 個 10 ms 的時間,這個查詢可真夠慢的。

為了讓一個查詢盡量少地讀磁盤,就必須讓查詢過程訪問盡量少的數據塊。那么,我們就不應該使用二叉樹,而是要使用“N 叉”樹。這里,“N 叉”樹中的“N”取決于數據塊的大小。

以 InnoDB 的一個整數字段索引為例,這個 N 差不多是 1200。這棵樹高是 4 的時候,就可以存 1200 的 3 次方個值,這已經 17 億了。考慮到樹根的數據塊總是在內存中的,一個 10 億行的表上一個整數字段的索引,查找一個值最多只需要訪問 3 次磁盤。其實,樹的第二層也有很大概率在內存中,那么訪問磁盤的平均次數就更少了。

N 叉樹由于在讀寫上的性能優點,以及適配磁盤的訪問模式,已經被廣泛應用在數據庫引擎中了。

數據庫引擎常用數據結構

B樹

B樹也稱B-樹,它是一顆多路平衡查找樹,B樹和后面講到的B+樹也是從最簡單的二叉樹變換而來的,并沒有什么神秘的地方,下面我們來看看B樹的定義。

  • 每個節點最多有m-1個關鍵字(可以存有的鍵值對)。

  • 根節點最少可以只有1個關鍵字。

  • 非根節點至少有m/2個關鍵字。

  • 每個節點中的關鍵字都按照從小到大的順序排列,每個關鍵字的左子樹中的所有關鍵字都小于它,而右子樹中的所有關鍵字都大于它。

  • 所有葉子節點都位于同一層,或者說根節點到每個葉子節點的長度都相同。

  • 每個節點都存有索引和數據,也就是對應的key和value。

472ac598b3bf9ef55a1a17be84d51cdf.png

B+樹

B+樹其實和B樹是非常相似的,我們首先看看相同點。

相同點:?根節點至少一個元素 非根節點元素范圍:m/2 <= k <= m-1

不同點:?B+樹有兩種類型的節點:內部結點(也稱索引結點)和葉子結點內部節點就是非葉子節點,內部節點不存儲數據,只存儲索引,數據都存儲在葉子節點。內部結點中的key都按照從小到大的順序排列,對于內部結點中的一個key,左樹中的所有key都小于它,右子樹中的key都大于等于它。葉子結點中的記錄也按照key的大小排列。?每個葉子結點都存有相鄰葉子結點的指針,葉子結點本身依關鍵字的大小自小而大順序鏈接。?父節點存有右孩子的第一個元素的索引。

f3f796760c57f6d428172a3ebb1094c3.png

總結

B和B+樹的區別在于,B+樹的非葉子結點只包含導航信息,不包含實際的值,所有的葉子結點和相連的節點使用鏈表相連,便于區間查找和遍歷。

B+ 樹的優點在于:

  1. 由于B+樹在內部節點上不包含數據信息,因此在內存頁中能夠存放更多的key。數據存放的更加緊密,具有更好的空間局部性。因此訪問葉子節點上關聯的數據也具有更好的緩存命中率。

  2. B+樹的葉子結點都是相鏈的,因此對整棵樹的便利只需要一次線性遍歷葉子結點即可。而且由于數據順序排列并且相連,所以便于區間查找和搜索。而B樹則需要進行每一層的遞歸遍歷。相鄰的元素可能在內存中不相鄰,所以緩存命中性沒有B+樹好。

但是B樹也有優點,其優點在于,由于B樹的每一個節點都包含key和value,因此經常訪問的元素可能離根節點更近,因此訪問也更迅速。

往期推薦

深入學習G1垃圾收集器

Redisson分布式鎖自動續期源碼分析

spring中發布訂閱模式實踐

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537361.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537361.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537361.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據倉如何支撐應用?

數據倉支撐應用&#xff0c;主要有以下步驟&#xff1a; 1.應用部門&#xff1a;在“寧波市公共數據目錄平臺”按需申請省市共享數據&#xff0c;申請的表審批通過后&#xff0c;提交《審批通過的表清單》給大數據中心&#xff1b; 2.大數據中心&#xff1a;比對《審批通過的…

辛苦倆月總結的面試題,掌握它懟翻面試官不是夢~

小編經過一個多月的不懈努力&#xff0c;給大家總結了一份面試方面的題目。這份面試題涉及高并發、分布式、高可用相關知識點&#xff0c;在此分享給大家&#xff0c;希望大家能拿到一份理想的 Offer&#xff01;因為是筆試題目&#xff0c;大家可以先做。如果需要查看答案&…

python坐標轉化極坐標_python 坐標系

廣告關閉提供包括云服務器&#xff0c;云數據庫在內的50款云計算產品。打造一站式的云產品試用服務&#xff0c;助力開發者和企業零門檻上云。寫在前面的話01 今天資源君帶大家學習一下python的可視化&#xff0c;何謂可視化呢&#xff1f; 我們常常聽說python的數據分析&#…

百家號 不被推薦,原因:將舊聞冒充新聞發布,請修改后重新發布

1.情景展示 在百家號進行創作的作者&#xff0c;發布文章時&#xff0c;難免會遇到審核不通過&#xff0c;下面說一下其中一種情況&#xff1a; 不被推薦&#xff0c;原因&#xff1a;將舊聞冒充新聞發布&#xff0c;請修改后重新發布. 2.解決方案 出現這種情況&#xff0c;原…

java字符串常量池——字符串==比較的一個誤區

轉自&#xff1a;https://blog.csdn.net/wxz980927155/article/details/81712342 起因 再一次js的json對象的比較中&#xff0c;發現相同內容的json對象使用比較并不相等。 例如&#xff1a; var obj {}; var obj2 {}; console.log(obj obj2); // 結果為false json在js中代表…

java注解_Java注解教程及自定義注解

Java注解提供了關于代碼的一些信息&#xff0c;但并不直接作用于它所注解的代碼內容。在這個教程當中&#xff0c;我們將學習Java的注解&#xff0c;如何定制注解&#xff0c;注解的使用以及如何通過反射解析注解。Java1.5引入了注解&#xff0c;當前許多java框架中大量使用注解…

Git設置忽略eclipse配置文件

概述 eclipse的配置文件是不能公用的&#xff0c;不同電腦上的eclipse配置文件內容是不一樣的&#xff0c;如果將eclipse配置文件上傳到了git&#xff0c;其他開發下載后&#xff0c;導入項目&#xff0c;有些報錯就是因為配置文件關系 操作 在git的忽略文件“.gitignore”里…

MySQL 時間函數

A. timestampdiff() 傳三個參數&#xff0c;第一個時間類型如年&#xff0c;月&#xff0c;日&#xff0c;第二個開始時間&#xff0c;第三個結束時間select test_name, timestampdiff(YEAR,create_time,end_time) y_date from test_table; --計算時間 -------------------| te…

jdk安裝包_第一章(第1節):安裝JDK

對于 jdk 的安裝&#xff0c;網上有很多種圖文解說&#xff0c;但是老鳥發現它們大都不嚴謹&#xff0c;非常不適合小白。本節課&#xff0c;老鳥就給大家做個小白教程&#xff0c;無論你多么菜&#xff0c;你一定可以安裝上&#xff0c;否則你加我微信&#xff0c;我給你打五毛…

eclipse 國內鏡像高速下載

概述 eclipse是優秀的老牌IDE&#xff0c;使用eclipse是一種身份的象征&#xff0c;代表了老程序員。eclipse每年都會更新&#xff0c;也越來越好用。但下載的時候&#xff0c;速度一直有點慢&#xff0c;eclipse官網提供了國內鏡像&#xff0c;下載很快。 操作步驟 第一步&…

matlab圖像去毛刺_警微圈 圖像處理第三講CLAHE

警微圈圖像處理100講 第三講《限制對比度自適應直方圖均衡化》- 圈語 -為給圈粉們提供一些結合公安工作的實用圖像處理方法&#xff0c;小編為大家準備了一些程序處理算法(附帶代碼)。小編使用的圖像處理軟件是matlab(該軟件關注警微圈后臺回復“matlab”即可獲得下載資源)&…

Java 使用 POI 操作 Excel

Apache POI 基本介紹 Apache POI 是 Apache 軟件基金會提供的 100% 開源庫。支持 Excel 庫的所有基本功能。 圖片來源&#xff1a;易百教程 基本概念 在 POI 中&#xff0c;Workbook代表著一個 Excel 文件&#xff08;工作簿&#xff09;&#xff0c;Sheet代表著 Workbook 中的…

Microsoft Project 變更項目日歷的注意事項

場景 今天在修改一份mpp排期計劃里的項目日歷&#xff0c;日歷是設置了周末2天加班&#xff0c;變更后發現&#xff0c;排期縮短的天數不對。一開始以為是Project軟件出問題了&#xff0c;與windows11不兼容&#xff0c;重啟了電腦&#xff0c;重試后還是這樣&#xff0c;后來…

python共享單車案例分析_python分析數據分析項目:共享單車租用情況影響因素探索分析...

python分析數據分析項目&#xff1a;共享單車租用情況影響因素探索分析

第十九節TypeScript 模塊

1、TypeScript模塊&#xff1a; 模塊是在其自身的作用域里執行&#xff0c;并不是在全局作用域&#xff0c;這意味著定義在模塊里面的變量、函數和類等在模塊外部是不可見的&#xff0c;除非明確地使用 export 導出它們。類似地&#xff0c;我們必須通過 import 導入其他模塊導…

微軟宣布 Edge 瀏覽器將切換至 Chromium 內核

簡述 據微軟官方 blog的消息&#xff0c;windows 的默認瀏覽器 Edge將切換內核至 Chromium&#xff0c;并且微軟將秉承開源精神&#xff0c;在未來更多的為 Chromium項目貢獻代碼。 微軟具體說了什么&#xff1f; 原文如下&#xff1a; For the past few years, Microsoft has …

解決the resource is not on the build path of a java project

場景 普通的Java project 轉maven 項目后&#xff0c;導入類提示&#xff1a;the resource is not on the build path of a java project 解決方法 將檢查java build source&#xff0c;將報錯的刪除&#xff0c;重新添加src資源包

python實現按回車鍵繼續程序_python實現按任意鍵繼續執行程序

在windows下寫bat的時候&#xff0c;通過pause命令&#xff0c;可以暫停程序運行&#xff0c;例如經常見的程序會在終端提示”按任意鍵繼續……”,用戶在終端回車后程序可以接著運行&#xff0c;這個功能有多大用途今天暫且不說&#xff0c;但我覺得應該有很多人也想在python下…

Beta

目錄 過去存在的問題任務分工規范后端總結卉卉家燦前端總結緒佩青元愷琳宇恒丹丹算法&API接口家偉鴻杰一好文檔&博客撰寫政演產品功能我們已經坐了哪些調整桌面控件合并我們會在Beta沖刺中做哪些改進組長博客&#xff1a;https://www.cnblogs.com/heihuifei/p/10084535…

項目驗收文檔合并技巧

1&#xff09;先將各個文件word寫好&#xff0c;格式&#xff0c;字體調整好&#xff1b; 2&#xff09;每個word導出PDF&#xff1b; 3&#xff09;將導出的PDF合并到一個大的PDF&#xff1b;