主頁 >  其他 > 聊聊Mysql索引和redis跳表

聊聊Mysql索引和redis跳表

2021-02-05 13:47:09 其他

聊聊Mysql索引和redis跳表 ---redis的有序集合zset資料結構底層采用了跳表原理 時間復雜度O(logn)(阿里)

redis使用跳表不用B+數的原因是:redis是記憶體資料庫,而B+樹純粹是為了mysql這種IO資料庫準備的,B+樹的每個節點的數量都是一個mysql磁區頁的大小(阿里面試)

敲黑板:

每級遍歷 3 個結點即可,而跳表的高度為 h ,所以每次查找一個結點時,需要遍歷的結點數為 3*跳表高度 ,所以忽略低階項和系數后的時間復雜度就是 ○(㏒n),空間復雜度是O(n)

問題

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

  • mysql 索引如何實作

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

  • 資料庫的索引還能有其他實作嗎

  • redis跳表是如何實作的

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

決議

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

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

資料集合的查找問題

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

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

  2. 插入/洗掉效率

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

  4. 存盤大小(空間復雜度)

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

hash

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

B+ 樹:

注意 這是關于B+樹的總結,如果你掌握到這個程度 是遠遠不夠的,

B+樹 的資料都在葉子節點,非葉子節點存放 索引

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

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

跳表

redis跳表視頻講解點擊鏈接:redis跳表

C/C++Linux服務器開發精彩內容包括:C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒體,P2P,Linux內核,Docker,TCP/IP,協程,DPDK多個高級知識點

學習視頻資料點擊:C/C++Linux服務器開發/Linux后臺架構師-學習視頻

C/C++Linux后臺服務器開發技術交流:技術qun

跳表:為什么 Redis 一定要用跳表來實作有序集合?

上幾篇主要是學習二分查找演算法,但是二分查找底層依賴的是陣列隨機訪問的特性,所以只能用陣列來實作,如果資料存盤在鏈表中,就沒辦法使用二分查找了嗎?

此時跳表出現了,跳表(Skip list) 實際上就是在鏈表的基礎上改造生成的,

跳表是一種各方面性能都比較優秀的 動態資料結構,可以支持快速的插入、洗掉、查找操作,寫起來也不復雜,甚至可以替代 紅黑樹??,

Redis 一共有5種資料結構,包括:

1、字串(String) redis對于KV的操作效率很高,可以直接用作計數器,例如,統計在線人數等等,另外string型別是二進制存盤安全的,所以也可以使用它來存盤圖片,甚至是視頻等,

2、哈希(hash) 存放鍵值對,一般可以用來存某個物件的基本屬性資訊,例如,用戶資訊,商品資訊等,另外,由于hash的大小在小于配置的大小的時候使用的是ziplist結構,比較節約記憶體,所以針對大量的資料存盤可以考慮使用hash來分段存盤來達到壓縮資料量,節約記憶體的目的,例如,對于大批量的商品對應的圖片地址名稱,比如:商品編碼固定是10位,可以選取前7位作為hash的key,后三位作為field,圖片地址作為value,這樣每個hash表都不超過999個,只要把redis.conf中的hash-max-ziplist-entries改為1024,即可, 3、串列(List) 串列型別,可以用于實作訊息佇列,也可以使用它提供的range命令,做分頁查詢功能,

4、集合(Set) 集合,整數的有序串列可以直接使用set,可以用作某些去重功能,例如用戶名不能重復等,另外,還可以對集合進行交集,并集操作,來查找某些元素的共同點

5、有序集合(zset) 有序集合,可以使用范圍查找,排行榜功能或者topN功能,

其中第五個zset 有序集合 就是用跳表來實作的,那 Redis 為什么會選擇用跳表來實作有序集合呢?

一、如何理解跳表?

對于單鏈表來說,我們查找某個資料,只能從頭到尾遍歷鏈表,此時時間復雜度是 ○(n),

那么怎么提高單鏈表的查找效率呢?看下圖,對鏈表建立一級 索引,每兩個節點提取一個結點到上一級,被抽出來的這級叫做 索引 或 索引層,

開發中經常會用到一種處理方式,hashmap 中存盤的值型別是一個 list,這里就可以把索引當做 hashmap 中的鍵,將每 2 個結點看成每個鍵對應的值 list,

所以要找到13,就不需要將16前的結點全遍歷一遍,只需要遍歷索引,找到13,然后發現下一個結點是17,那么16一定是在 [13,17] 之間的,此時在13位置下降到原始鏈表層,找到16,加上一層索引后,查找一個結點需要遍歷的結點個數減少了,也就是說查找效率提高了

那么我們再加一級索引呢? 跟前面建立一級索引的方式相似,我們在第一級索引的基礎上,每兩個結點就抽出一個結點到第二級索引,此時再查找16,只需要遍歷 6 個結點了,需要遍歷的結點數量又減少了,

當結點數量多的時候,這種添加索引的方式,會使查詢效率提高的非常明顯

二、用跳表查詢到底有多快

在一個單鏈表中,查詢某個資料的時間復雜度是 ○(n),那在一個具有多級索引的跳表中,查詢某個資料的時間復雜度是多少呢?

按照上面的示例,每兩個節點就抽出一個一級索引,每兩個一級索引又抽出一個二級索引,所以第一級索引的結點個數大約就是 n/2,第二級索引的結點個數就是 n/4,第 k 級索引的結點個數就是 n/2^k,

假設一共建立了 h 級索引,最高級的索引有兩個節點(如果最高級索引只有一個結點,那么這一級索引起不到判斷區間的作用,那么是沒什么意義的),所以有:

時間復雜度的分析

根據上圖得知,每級遍歷 3 個結點即可,而跳表的高度為 h ,所以每次查找一個結點時,需要遍歷的結點數為 3*跳表高度 ,所以忽略低階項和系數后的時間復雜度就是 ○(㏒n)

其實此時就相當于基于單鏈表實作了二分查找,但是這種查詢效率的提升,由于建立了很多級索引,會不會很浪費記憶體呢?

三、跳表是不是很浪費記憶體?

來分析一下跳表的空間復雜度, 為O(n)

空間復雜度

所以如果將包含 n 個結點的單鏈表構造成跳表,我們需要額外再用接近 n 個結點的存盤空間,那怎么才能降低索引占用的記憶體空間呢?

前面是每兩個結點抽一個結點到上級索引,如果我們每三個,或每五個結點,抽一個結點到上級索引,是不是就不用那么多索引結點了呢?

計算空間復雜度的程序與前面的一致,盡管最后空間復雜度依然是 ○(n),但我們知道,使用大○表示法忽略的低階項或系數,實際上同樣會產生影響,只不過我們為了關注高階項而將它們忽略,

空間復雜度

實際上,在實際開發中,我們不需要太在意索引占據的額外空間,在學習資料結構與演算法時,我們習慣的將待處理資料看成整數,但是實際開發中,原始鏈表中存盤的很可能是很大的物件,而索引結點只需要存盤關鍵值(用來比較的值)和幾個指標(找到下級索引的指標),并不需要存盤原始鏈表中完整的物件,所以當物件比索引結點大很多時,那索引占用的額外空間就可以忽略了,

四、高效的動態插入和洗掉

跳表這個動態資料結構,不僅支持查找操作,還支持動態的插入、洗掉操作,而且插入、洗掉操作的時間復雜度也是 ○(㏒n),

對于單純的單鏈表,需要遍歷每個結點來找到插入的位置,但是對于跳表來說,因為其查找某個結點的時間復雜度是 ○(㏒n),所以這里查找某個資料應該插入的位置,時間復雜度也是 ○(㏒n),

那么洗掉操作呢?

五、跳表索引動態更新

當我們不停的往跳表中插入資料時,如果我們不更新索引,就可能出現某 2 個索引結點之間資料非常多的情況,極端情況下,跳表會退化成單鏈表,

作為一種動態資料結構,我們需要某種手段來維護索引與原始鏈表大小之間的平滑,也就是說如果鏈表中結點多了,索引結點就相應地增加一些,避免復雜度退化,以及查找、插入、洗掉操作性能下降,

跳表是通過隨機函式來維護前面提到的 平衡性,

我們往跳表中插入資料的時候,可以選擇同時將這個資料插入到第幾級索引中,比如隨機函式生成了值 K,那我們就將這個結點添加到第一級到第 K 級這 K 級索引中,

隨機函式可以保證跳表的索引大小和資料大小的平衡性,不至于性能過度退化,

跳表的實作有點復雜,并且跳表的實作并不是這篇的重點,主要是學習思路,

六、解答開篇

Redis 中的有序集合是通過跳表來實作的,嚴格點講,還用到了散串列,如果查看 Redis 開發手冊,會發現 Redis 中的有序集合支持的核心操作主要有下面這幾個:

  • 插入一個資料

  • 洗掉一個資料

  • 查找一個資料

  • 按照區間查找資料(比如查找在[100,356]之間的資料)

  • 迭代輸出有序序列

其中,插入、查找、洗掉以及迭代輸出有序序列這幾個操作,紅黑樹也能完成,時間復雜度和跳表是一樣的,但是,按照區間來查找資料這個操作,紅黑樹的效率沒有跳表高,

對于按照區間查找資料這個操作,跳表可以做到 ○(㏒n) 的時間復雜度定位區間的起點,然后在原始鏈表中順序往后遍歷就可以了,這樣做非常高效,

當然,還有其他原因,比如,跳表代碼更容易實作,可讀性好不易出錯,跳表更加靈活,可以通過改變索引構建策略,有效平衡執行效率和記憶體消耗,

不過跳表也不能完全替代紅黑樹,因為紅黑樹出現的更早一些,很多編程語言中的 Map 型別都是用紅黑樹來實作的,寫業務的時候直接用就行,但是跳表沒有現成的實作,開發中想用跳表,得自己實作,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/256762.html

標籤:其他

上一篇:FPGA 折疊 近似計算實作卷積

下一篇:運維:生產日志重復列印了,趕緊來看看~

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more