【Mysql】InnoDB 中 B+ 樹索引的注意事項

一、根頁面萬年不動

在之前的文章里,為了方便理解,都是先畫存儲用戶記錄的葉子節點,然后再畫出存儲目錄項記錄的內節點。

但實際上 B+ 樹的行成過程是這樣的:

  • 每當為某個表創建一個 B+ 樹索引,都會為這個索引創建一個根節點頁面。最開始表里沒數據,所以根節點中既沒有用戶記錄,也沒有目錄項記錄。

  • 當往表里插入用戶記錄時,先把用戶記錄存儲到這個根節點上。

  • 當根節點頁空間用完,繼續插入記錄,此時會將根節點中所有記錄復制到一個新頁(比如頁 a),然后對這個新頁進行頁分裂,得到另一個新頁(頁 b)。這時候新插入的記錄就根據鍵值大小分配到頁 a 和 頁 b 中。于是,根節點頁就升級成了存儲目錄項記錄的頁,就需要把頁a 和 頁b 對應的目錄項記錄插入到根節點中。

另外,當一個B+樹索引的根節點創建后,它的頁號就不會再變

所以只要我們對某個表建立一個索引,那么它的根節點的頁號就會被記錄到某個地方,后續只要 innodb引擎需要用這個索引,就會從那個固定的地方取出根節點的頁號,從而訪問這個索引。

二、內節點中目錄項記錄的唯一性

在B+樹索引的內節點中,目錄項記錄的內容是索引列+頁號。但是對于二級索引來說,不太嚴謹。

因為二級索引的索引列可能存在相同的值,比如某張表里有這4條記錄,其中c1列是主鍵 :

現在為c2列建立索引:

如果這時候繼續插入一條記錄,3個列分別為9、1、'c',就會遇到問題:

  • 新記錄中 c2的值也是1,那么這個新記錄到底應該放在頁 4,還是放到頁 5?

所以,為了能讓新插入的記錄可以找到自己應該到哪個頁中,就需要保證B+樹同一層內節點的目錄項記錄是唯一的

那么,實際上二級索引的內節點的目錄項記錄應該由 3 個部分組成:

  • 索引列的值
  • 主鍵值
  • 頁號

所以實際上給c2建立的索引應該是這樣:

現在,當插入新記錄9、1、'c'時:

  • 可以先把新記錄的 c2 列的值和頁 3 中各目錄項記錄的 c2 列的值進行比較。
  • 如果 c2 列的值相同,就接著比較主鍵值。

所以,對于二級索引來說,給 c2 列建索引,其實就相當于用c2、c1建立了一個聯合索引。先按照二級索引的值進行排序,在二級索引列值相同的情況下,再按照主鍵值進行排序。

三、一個頁面至少容納 2 條記錄

在之前的文章里提到過,B+ 樹其實只需要很少的層級就可以輕松存儲數億條記錄,查詢速度還很快。

這是因為 B+ 樹本質上就是一個大的多層級目錄。每經過一個目錄時都會過濾許多無效的子目錄,直到最后訪問到存儲真正數據的目錄。

那么現在不妨設想一下:還是同樣的數據量,如果一個大的目錄只存放一個子目錄,又是什么樣子?

  • 目錄層級非常多
  • 最后那個存放真正數據的目錄中只能存放一條記錄

如果是這樣的話,這種B+ 樹結構就沒什么意義了,不能形成一個有效的索引。于是,設計 innoDB的大佬為了避免 B+樹的層級增長得過高,要求所有數據頁都至少可以存放2條記錄

最后感謝每一個認真閱讀我文章的人,禮尚往來總是要有的,這些資料,對于【軟件測試】的朋友來說應該是最全面最完整的備戰倉庫,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:

這些資料,對于【軟件測試】的朋友來說應該是最全面最完整的備戰倉庫,這個倉庫也陪伴上萬個測試工程師們走過最艱難的路程,希望也能幫助到你!?

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

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

相關文章

C++高級面試題:請解釋 C++ 中的標準模板庫(STL)及其常見組件

請解釋 C 中的標準模板庫(STL)及其常見組件 C 標準模板庫(Standard Template Library,STL)是 C 標準庫的一部分,提供了豐富的通用數據結構和算法實現,以及許多與數據處理相關的工具。STL 中的組…

循環隊列的實現

文章目錄 循環隊列的概念循環隊列的實現循環隊列的判空和判滿鏈表or數組 循環隊列的概念 設計你的循環隊列實現。 循環隊列是一種線性數據結構,其操作表現基于 FIFO(先進先出)原則并且隊尾被連接在隊首之后以形成一個循環。它也被稱為“環形緩…

快速下載Huggingface的大語言模型

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言一、Huggingface是什么?二、基于官方huggingface-cli下載(基礎,斷線風險)1.安裝hf下載環境2.配置環境變量3.注冊…

CSAPP-信息的表示和處理

文章目錄 概念掃盲思想理解經典好圖安全事件 概念掃盲 1.大端高位在前,小端低位在前 2.邏輯運算符(&& 、||、!)與位級運算(&、|、~)的差異 3.宏可以保證無論代碼如何編譯,都能生成…

flutterandroidx支持,【工作經驗分享】

基于Linux的pc啟動過程 我們都知道,所有的程序軟件包括操作系統都是運行在內存中的,然而我們的操作系統一般是存放在硬盤上的,當我們按下開機鍵的時候,此時內存中什么程序也沒有,因此需要借助某種方式,將操…

百度SEO工具,自動更新網站的工具

在網站SEO的過程中,不斷更新網站內容是提升排名和吸引流量的關鍵之一。而對于大多數網站管理員來說,頻繁手動更新文章并進行SEO優化可能會是一項繁瑣且耗時的任務。針對這一問題,百度自動更新文章SEO工具應運而生,它能夠幫助網站管…

搭建nginx+keepalived高可用(主備模式)

nginx安裝 1. 前置依賴安裝 yum install gcc gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel -y2. 編譯安裝nginx nginx下載地址: https://nginx.org/en/download.html ## 安裝包位置:信息港16.11:/root/shl tar xvf nginx-1.20.2.ta…

chartjs 餅狀圖

之前要把canvas先清除掉&#xff0c;不然刷新數據&#xff0c;還會有前面的圖表 function clearCanvas(){$(#donutChart).remove();$(#chartdiv).append(<canvas id"donutChart" style"min-height: 500px; height: 500px; max-height: 500px; max-width: 70%…

淺談mysql mvcc

目錄 前言 mvcc 是如何工作的&#xff1f; 數據的更新 前言 mvcc 與一個事物的隔離級別有關&#xff0c;未提交讀永遠讀的是當前值&#xff0c;串行化是通過加鎖實現&#xff0c;這兩種隔離級別都與mvcc 沒有任何關系。只要一提到mvcc應該想到的是讀提交以及可重復讀&#…

vue+element ui上傳圖片到七牛云服務器

本來打算做一個全部都是前端完成的資源上傳到七牛云的demo&#xff0c;但是需要獲取token&#xff0c;經歷了九九八十一難&#xff0c;最終還是選擇放棄&#xff0c;token從后端獲取&#xff08;springboot&#xff09;。如果你們有前端直接能解決的麻煩記得私我哦&#xff01;…

『Linux從入門到精通』第 ? 期 - 動靜態庫

文章目錄 &#x1f490;專欄導讀&#x1f490;文章導讀&#x1f427;什么是庫&#xff1f;&#x1f427;為什么要有庫&#xff1f;&#x1f427;寫一個自己的庫&#x1f426;方法一&#x1f426;方法二 靜態庫&#x1f426;標準化&#x1f426;方法三 動態庫&#x1f426;配置動…

python中自定義報錯

class MyError(Exception):def __init__(self,num):#錄入的數Exception.__init__(self)self.numnumdef __str__(self):return 這是我定義的第%d個異常 %(self.num)使用 try:raise MyError(4) except MyError as e:print(e)raise 其作用是指定拋出的異常名稱&#xff0c;以及異常…

題目 1240: 生日日數

題目描述: CCC老師的生日是YY年MM月DD日&#xff0c;他想知道自己出生后第一萬天紀念日的日期&#xff08;出生日算第0天&#xff09;。 代碼: package lanqiao;import java.time.LocalDate; import java.util.*;public class Main {public static void main(String[] args)…

數據結構題目①——數組

前言 本篇文章為博主進行代碼隨想錄——數組練習后的總結會涉及到每一道題目的詳細的思路整理&#xff0c;以及本人的易錯點&#xff0c;希望對大家有所幫助 數組介紹&#xff1a; 數組在C語言中就已經有所涉及&#xff0c;它是一個最基礎的數據結構&#xff0c;而在數據結構中…

Java學習—FileInputStream

在Java編程中&#xff0c;文件操作是日常任務之一。無論是讀取配置文件、處理圖像&#xff0c;還是讀寫日志文件&#xff0c;理解如何有效地進行文件讀取都是非常重要的。Java提供了多種方式來操作文件&#xff0c;而FileInputStream是其中最基礎也是最直接的一種。本文將深入探…

Spring面試系列-01

1. 什么是 Spring 框架? Spring中文翻譯過來是春天的意思,被稱為J2EE的春天,是一個開源的輕量級的Java開發框架, 具有控制反轉(IoC)和面向切面(AOP)兩大核心。Java Spring框架通過聲明式方式靈活地進行事務的管理,提高開發效率和質量。 Spring框架不僅限于服務器端的…

three 層級模型

group.remove(mesh1,mesh2);Vector3與模型位置、縮放屬性 Group層級模型(樹結構) 創建了兩個網格模型mesh1、mesh2&#xff0c;通過THREE.Group類創建一個組對象group,然后通過add方法把網格模型mesh1、mesh2作為設置為組對象group的子對象&#xff0c;然后在通過執行scene.a…

jenkins部署maven項目

流程&#xff1a; jenkins從代碼倉庫讀取代碼&#xff0c;將代碼文件放入jenkins的工作空間&#xff0c;將jenkins工作空間的代碼進行打包&#xff0c;將jar包遠程發送給服務器。 一&#xff1a;所需插件二&#xff1a;Tools 三&#xff1a;System&#xff1a; 配置ssh連接的…

github要求2fa身份驗證

前言 github登陸的時候發現要求2fa驗證, 2fa是啥?咋驗證? 解決 2FA&#xff08;Two-Factor Authentication&#xff0c;雙因素身份驗證&#xff09; 就是在賬戶和密碼的基礎上增加一次驗證碼驗證,這樣即使密碼被竊取,由于黑客沒有你的驗證碼也無法登陸 就像是銀行的u盾一樣…

python63-Python的循環之循環使用else

Python的循環都可以定義else代碼塊&#xff0c;當循環條件為False 時&#xff0c;程序會執行else代碼塊。如下代碼示范了為while循環定義else代碼塊。 # !/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2024/01# Author : Laopicount_i 0while count_i < 5:print(c…