mysql 跳表 b 樹_簡單談談Mysql索引與redis跳表

摘要

面試時,交流有關mysql索引問題時,發現有些人能夠濤濤不絕的說出B+樹和B樹,平衡二叉樹的區別,卻說不出B+樹和hash索引的區別。這種一看就知道是死記硬背,沒有理解索引的本質。本文旨在剖析這背后的原理,歡迎留言探討

問題

如果對以下問題感到困惑或一知半解,請繼續看下去,相信本文一定會對你有幫助

mysql 索引如何實現

mysql 索引結構B+樹與hash有何區別。分別適用于什么場景

數據庫的索引還能有其他實現嗎

redis跳表是如何實現的

跳表和B+樹,LSM樹有和區別呢

解析

首先為什么要把mysql索引和redis跳表放在一起討論呢,因為他們解決的都是同一種問題,用于解決數據集合的查找問題,即根據指定的key,快速查到它所在的位置(或者對應的value)

當你站在這個角度去思考問題時,還會不知道B+樹索引和hash索引的區別嗎

數據集合的查找問題

現在我們將問題領域邊界劃分清楚了,就是為了解決數據集合的查找問題。這一塊需要考慮哪些問題呢

需要支持哪些查找方式,單key/多key/范圍查找,

插入/刪除效率

查找效率(即時間復雜度)

存儲大小(空間復雜度)

我們看下幾種常用的查找結構

hash

5797a0e1fcbf69ccd841d4a16ba56502.png

hash是key,value形式,通過一個散列函數,能夠根據key快速找到value

B+樹

ca060a5edb76d4f84b983458a98e1ddd.png

B+樹是在平衡二叉樹基礎上演變過來,為什么我們在算法課上沒學到B+樹和跳表這種結構呢。因為他們都是從工程實踐中得到,在理論的基礎上進行了妥協。

B+樹首先是有序結構,為了不至于樹的高度太高,影響查找效率,在葉子節點上存儲的不是單個數據,而是一頁數據,提高了查找效率,而為了更好的支持范圍查詢,B+樹在葉子節點冗余了非葉子節點數據,為了支持翻頁,葉子節點之間通過指針連接。

跳表

ef772d518a40ff3823c94170f263e07f.png

跳表是在鏈表的基礎上進行擴展的,為的是實現redis的sorted set數據結構。 level0: 是存儲原始數據的,是一個有序鏈表,每個節點都在鏈上 level0+: 通過指針串聯起節點,是原始數據的一個子集,level等級越高,串聯的數據越少,這樣可以顯著提高查找效率,

總結

數據結構

實現原理

key查詢方式

查找效率

存儲大小

插入、刪除效率

Hash

哈希表

支持單key

接近O(1)

小,除了數據沒有額外的存儲

O(1)

B+樹

平衡二叉樹擴展而來

單key,范圍,分頁

O(Log(n)

除了數據,還多了左右指針,以及葉子節點指針

O(Log(n),需要調整樹的結構,算法比較復雜

跳表

有序鏈表擴展而來

單key,分頁

O(Log(n)

除了數據,還多了指針,但是每個節點的指針小于<2,所以比B+樹占用空間小

O(Log(n),只用處理鏈表,算法比較簡單

對LSM結構感興趣的可以看下cassandra vs mongo (1)存儲引擎

cassandra vs mongo (1)存儲引擎

概括

存儲引擎:

079baefc26e655bdc473b5fb2356c651.png

B-Tree

緩存管理

緩存管理的核心在于置換算法,置換算法常見的有FIFO(First In First Out),LRU(Least Recently Used)。關系型數據庫在LRU的基礎上,進行了改進,主要使用LIRS(Low Inter-reference Recency Set)

將緩存分為兩級,第一次采用LRU,最近被使用到的數據會進第一級,如果數據在較短時間內被訪問了兩次或以上,則成為熱點數據,進入第二級。避免了進行全表掃描的時候,可能會將緩存中的大量熱點數據替換掉。

LSM

Log-Structured Merge Tree:結構化合并樹,核心思想就是不將數據立即從內存中寫入到磁盤,而是先保存在內存中,積累了一定量后再刷到磁盤中

LSM VS B-Tree

LSM在B-Tree的基礎上為了獲取更好的寫性能而犧牲了部分的讀性能,同時利用其它的實現來彌補讀性能,比如boom-filter.

1.寫

B樹的寫入,是首先找到對應的塊位置,然后將新數據插入。隨著寫入越來越多,為了維護B樹結構,節點得分裂。這樣插入數據的隨機寫概率就會增大,性能會減弱。

LSM 則是在內存中形成小的排好序的樹,然后flush到磁盤的時候不斷的做merge.因為寫入都是內存寫,不寫磁盤,所以寫會很高效。

2.讀

B樹從根節點開始二分查詢直到葉子節點,每次讀取一個節點,如果對應的頁面不在內存中,則讀取磁盤,緩存數據。

LSM樹整個結構不是有序的,所以不知道數據在什么地方,需要從每個小的有序結構中做二分查詢,找到了就返回,找不到就繼續找下一個有序結構。所以說LSM犧牲了讀性能。但是LSM之所以能夠作為大規模數據存儲系統在于讀性能可以通過其他方式來提高,比如讀取性能更多的依賴于內存/緩存命中率而不是磁盤讀取。

Cassandra

Cassandra是一個寫性能優于讀性能的NoSql數據庫,寫性能好一個原因在于選擇了LSM存儲引擎。

Mongo

MMAPv1

Mongo 3.2以前默認使用MMAPv1存儲引擎,是基于B-Tree類型的。

邊界(padding)

MMAPv1 存儲引擎使用一個叫做”記錄分配”的過程來為document存儲分配磁盤空間。MongoDB與Cassandra不同的是,需要去更新原有的document。如果原有的document空間不足,則需要將這個document移動到新的位置,更新對應的index。這樣就會導致一些不必要的更新,和數據碎片。

為了避免出現上述情況,就有了邊界的概念,就是為document預分配空間。但是這樣就有可能造成資源的浪費。mongo 按照64M,128M,256M…2G的2的冥次方遞增策略預分配,最大2G。在數據量小的情況下問題并不明顯,但是當達到2G時,磁盤占用量大的問題就出來了。

同樣這一點和關系型數據庫也不一樣,關系型數據庫對于長記錄數據會分開存儲。

MMAPv1使用collection級別的鎖,即一個collecion增,刪,改一次只能有一個。在并發操作時,就會造成等待。

WiredTiger

3.2及其以后的默認存儲引擎,同樣是基于B-Tree的。采用了lock-free,風險指針等并發技術,使得在多核機器上工作的更好。

鎖級別為document。并且引入了compression,減少了磁盤占用。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

您可能感興趣的文章:新手學習MySQL索引

由不同的索引更新解決MySQL死鎖套路

通過唯一索引S鎖與X鎖來了解MySQL死鎖套路

分享幾道關于MySQL索引的重點面試題

Mysql中的索引精講

MySQL學習(七):Innodb存儲引擎索引的實現原理詳解

使用shell腳本來給mysql加索引的方法

MySQL批量插入和唯一索引問題的解決方法

高效利用mysql索引指南

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

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

相關文章

(Ajax)axios源碼簡析(三)——請求與取消請求

傳送門&#xff1a; axios源碼簡析&#xff08;一&#xff09;——axios入口文件axios源碼簡析&#xff08;二&#xff09;——Axios類與攔截器axios源碼簡析&#xff08;三&#xff09;——請求與取消請求請求過程 在Axios.prototype.request中我們看到&#xff0c;要先通過請…

Windows配置tomcat環境

1、安裝JDK 參考教程&#xff1a; https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.htmlCLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarCLASSPATH這個環境變量一定要配好&#xff0c;否則tomcat起不來&#xff0c;直接復制上面的內容&#xff0c;…

java 抽獎 高并發處理_如何設計高并發下的抽獎?

關于抽獎,需要考慮的點有很多,這里稍微整理了下主要需要考慮以下三點:用戶抽獎次數限制獎品數量限制獎品發放的分布中獎的概率的可控性用戶抽象次數限制一個用戶必須限制抽獎的次數,而同一個用戶的并發幾率其實是很小的,所以這里可以用悲觀鎖來控制用戶的抽獎次數。獎品數量限制…

WPF圓角按鈕與觸發顏色變化

原文:WPF圓角按鈕與觸發顏色變化<Button x:Name"button1" Content"按鈕1" Margin"10,10,0,0" Cursor"Pen"><Button.Template><ControlTemplate><Border CornerRadius"15,15,15,15"><Border.Back…

咖啡豆的勵志故事

好多年前就聽過這個故事&#xff0c;以前沒感觸&#xff0c;最近特有感觸。

java bean spring_JavaBean和Spring bean傻傻分不清楚

JavaBean的定義可序列化提供無參構造提供getter/setter方法疑問在學習 Spring 的過程中發現很多 bean 對象并沒有實現 Serializable 接口或提供其他可序列化的操作。這種也叫 bean&#xff1f;或者 bean 也可以不提供序列化操作&#xff1f;解決stackoverflow 一番后&#xff0…

WPF Image Source 設置相對路徑圖片

原文:WPF Image Source 設置相對路徑圖片BitmapImage bt new BitmapImage(new Uri("Images\\3_u10484.png", UriKind.Relative));this.Img1.Source bt;

PowerDesigner V16.5 安裝教程以及漢化(數據庫建模)

原文地址&#xff1a;https://blog.csdn.net/tgbyn/article/details/72809116 ----------------------------------------------------------------------一、power designer是什么以及是干什么的&#xff1f; power designer是能進行數據庫設計的強大的軟件&#xff0c;是一款…

python調用jar字典類型_LWPCookieJar的使用-將requests存儲的cookie轉換成字典

LWPCookieJar是python中管理cookie的工具&#xff0c;可以將cookie保存到文件&#xff0c;或者在文件中讀取cookie數據到程序寫入cookie到文件from cookielib import LWPCookieJarcj LWPCookieJar()cj.set_cookie(cookielib.Cookie(version0,names_cookie[name],values_cookie…

常用的數字正則匹配

1. 數字 ^[0-9]*$2. 1-60之間的整數 /^([1-5][0-9]$)|(^[6][0]$)|(^[1-9])$/ 3. 0-60的數字&#xff0c;可以精確到小數點后2位 /^(([0-5][0-9])|[0-9]|60|(([0-9]\.\d{1,2}|[1-5][0-9]\.\d{1,2})))$/ 4. 0-1000000的整數  /^(?!00)(?:[0-9]{1,7}|1000000)$/5. 5-10000…

nginx 代理多個服務器——多個server方式

原文鏈接&#xff1a;https://blog.csdn.net/wild46cat/article/details/52997005 ------------------------------------------------------------- 配置文件下載地址&#xff1a;https://download.csdn.net/download/zengmingen/10462400nginx 代理多個服務器——多個server方…

sc openscmanager 失敗 5 mysql_如何增加windows服務

我以前也出現過你這個問題&#xff0c;用優化大師給刪了吧&#xff0c;后來也是重裝的&#xff0c;其實說是重裝也不是重裝&#xff0c;就是修復啦&#xff0c;如果你不想這樣&#xff0c;那可以試試這個&#xff0c;我沒試過用在mysql上&#xff0c;但別的到是用他加載過。讓程…

TemplatePart用法說明

原文:TemplatePart用法說明TemplatePart(Name"PART_Decrease", Typetypeof(RepeatButton)) 一直沒明白這是干嘛用的&#xff0c;搜了一下&#xff0c;記載一下。 以Button的定義為例&#xff1a; namespace System.Windows.Controls {// Summary:// Represents a…

nginx配置多個站點共用80端口

原文鏈接&#xff1a;https://blog.csdn.net/zhezhebie/article/details/73459874 --------------------------------------------- 配置文件下載地址&#xff1a;https://download.csdn.net/download/zengmingen/10462400共用80端口的&#xff0c;要server_name不同。如果用域…

兩點間最短路 java_AcWing 850. Dijkstra求最短路 II_Java實現含詳細注釋

import java.io.*;import java.util.Arrays;import java.util.Comparator;import java.util.PriorityQueue;public class Main {static final int N 150010;static int n, m; //結點數&#xff0c;邊數static int[] h, e, ne, w; //鄰接表適合表示稀疏圖,w用來存每個邊權重sta…

SQL Server如何鏈接到 Oracle并查詢其中的數據?并實現做接口

今天用Oracle的驅動教大家如何從SQL Server鏈接到Oracle. 1. 服務器上需要安裝Oracle 64位的客戶端或者服務端&#xff0c;安裝過程就省略了。不會的同學可以網上搜索一下安裝方法&#xff0c;很詳細&#xff0c;這里不贅述。 安裝完成后SQL Server的訪問接口上會新增”OraOLE…

Tomcat 內存調大

第一種方法&#xff1a;Windows下&#xff0c;在文件/bin/catalina.bat&#xff0c;Unix下&#xff0c;在文件/bin/catalina.sh的前面&#xff0c;增加如下設置&#xff1a;JAVA_OPTS-Xms【初始化內存大小】 -Xmx【可以使用的最大內存】需要把這個兩個參數值調大。例如&#xf…

java spring bean配置文件_Spring基于xml文件配置Bean過程詳解

這篇文章主要介紹了spring基于xml文件配置Bean過程詳解,文中通過示例代碼介紹的非常詳細&#xff0c;對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下通過全類名來配置&#xff1a;class&#xff1a;bean的全類名&#xff0c;通過反射的方式在IOC容器中創建B…

win10升級后chrome碰到對話框就卡死

低版本的 chrome 會出現這樣的問題 解決方法&#xff1a; 設置-------高級設置-----取消硬件加速

客戶端SDK測試思路

本文來自網易云社區作者&#xff1a;萬春艷是什么客戶端SDK是為第三方開發者提供的軟件開發工具包&#xff0c;包括SDK接口、開發文檔和Demo示例等。SDK和應用之間是什么關系呢&#xff1f;以云信即時消息服務為例&#xff0c;如下圖所示&#xff0c;應用客戶端通過調用云信SDK…