Redis的五大數據類型的數據結構

来源:https://www.cnblogs.com/fhey/archive/2023/08/29/17666010.html
-Advertisement-
Play Games

概述 Redis底層有六種數據類型包括:簡單動態字元串、雙向鏈表、壓縮列表、哈希表、跳錶和整數數組。這六種數據結構五大數據類型關係如下: String:簡單動態字元串 List:雙向鏈表、壓縮列表 Hash:壓縮列表、哈希表 Sorted Set:壓縮列表、跳錶 Set:哈希表、整數數組 數據類型和 ...


概述

  Redis底層有六種數據類型包括:簡單動態字元串、雙向鏈表、壓縮列表、哈希表、跳錶和整數數組。這六種數據結構五大數據類型關係如下:

  • String:簡單動態字元串
  • List:雙向鏈表、壓縮列表
  • Hash:壓縮列表、哈希表
  • Sorted Set:壓縮列表、跳錶
  • Set:哈希表、整數數組

          數據類型和底層數據結構對應關係

 

  每種數據結構特性不一樣,操作時間也不一樣。

        數據結構的時間複雜度

 

二、數據結構

  從上述圖中可以知道,Redis的底層數據結構由簡單動態字元串、雙向鏈表、壓縮列表、哈希表、跳錶、整數數組組成,其中哈希表和整數數組基本上大家都很熟悉了,下麵重點介紹一下其餘的幾種數據結構。

1、簡單動態字元串(SDS)

  結構:alloc,len,buf

        簡單動態字元串結構

 

  buf:位元組數組,保存實際數據。為了表示位元組數組的結束,Redis 會自動在數組最後加一個“\0”,這就會額外占用 1 個位元組的開銷。

  len:占 4 個位元組,表示 buf 的已用長度。

  alloc:也占個 4 位元組,表示 buf 的實際分配長度,一般大於 len。

  那麼SDS與C字元串有什麼區別呢?區別主要有如下兩點:

  (1)獲取字元串長度時間複雜度為O(1)

  (2)在修改字元串時,會先檢查長度是否夠長,不夠會進行擴展,避免緩衝區溢出

 

2、鏈表

  Redis使用的是雙向無環鏈表,並且具有以下幾個特點:

  (1)雙端:鏈表具有前置節點和後置節點的引用,獲取這兩個節點時間複雜度都為O(1)。

  (2)無環:表頭節點的 prev 指針和表尾節點的 next 指針都指向 NULL,對鏈表的訪問都是以 NULL 結束。

  (3)帶鏈表長度計數器:通過 len 屬性獲取鏈表長度的時間複雜度為 O(1)。

  (4)多態:鏈表節點使用 void* 指針來保存節點值,可以保存各種不同類型的值。

 

3、壓縮列表

  壓縮列表(ziplist)是Redis為了節省記憶體而開發的,是由一系列特殊編碼的連續記憶體塊組成的順序型數據結構,一個壓縮列表可以包含任意多個節點(entry),每個節點可以保存一個位元組數組或者一個整數值。壓縮列表並不是對數據利用某種演算法進行壓縮,而是將數據按照一定規則編碼在一塊連續的記憶體區域,目的是節省記憶體。

壓縮列表實際上類似於一個數組,數組中的每一個元素都對應保存一個數據。和數組不同的是,壓縮列表在表頭有三個欄位 zlbytes、zltail 和 zllen,分別表示列表長度、列表尾的偏移量和列表中的 entry 個數;壓縮列表在表尾還有一個 zlend,表示列表結束;

我們要查找定位第一個元素和最後一個元素,可以通過表頭三個欄位的長度直接定位,複雜度是 O(1)。而查找其他元素時,就沒有這麼高效了,只能逐個查找,此時的複雜度就是 O(N) 了。

          壓縮表的查找過程

 

 

4、跳錶

  跳錶在鏈表的基礎上,增加了多級索引,通過索引位置的幾個跳轉,實現數據的快速定位,時間複雜度為O(logN),比起鏈表,跳錶的查詢效率大大提高到了 O(logn)。

        跳錶查找過程

 

三、Redis數據類型的基本數據結構

1、String(字元串)

  1.1 String的內部結構

  redis沒有直接使用C語言中的字元串表示,而是自己構建了一個字元串,名為 “簡單動態字元串” (simple dynamic string , SDS)。其中,C語言中的字元串只是作為字元串面量(通常在無須對字元串值進行修改的地方使用)。

 

  String在結構上的實現類似於Java中的ArrayList(預設構造一個大小為10的初始數組),這是冗餘分配記憶體的思想,也稱為預分配;這種思想可以減少擴容帶來的性能消耗。

              String的內部結構

 

1.2 String使用的數據編碼

  存儲數字的話,採用int類型的編碼,如果是非數字的話,採用 raw 編碼;

 

1.3 使用場景

  (1) 簡單字元緩存

  (2) 分散式鎖

  (3)計數功能——》計數服務

 

2、List(列表)

2.1 List的內部結構

  Redis的列表相當於Java語言中的LinkedList,它是一個雙向鏈表數據結構(但是這個結構設計比較巧妙,後面會介紹),支持前後順序遍歷。鏈表結構插入和刪除操作快,時間複雜度O(1),查詢慢,時間複雜度O(n)。

                List的內部結構

 

2.2 List使用的數據編碼

  字元串長度及元素個數小於一定範圍使用 ziplist 編碼,任意條件不滿足,則轉化為 linkedlist 編碼。

 

2.3 使用場景

  (1)利用List實現棧、隊列

  (2)redis做消息隊列(不推薦使用redis做消息隊列)

  (3)列表緩存

 

3、Hash(字典)

3.1 Hash的內部結構

  Redis的hash(字典)相當於Java語言中的HashMap,它是根據散列值分佈的無序字典,內部的元素是通過鍵值對的方式存儲。

  hash(字典)的實現與Java中的HashMap(JDK1.7)的結構也是一致的,它的數據結構也是數組+鏈表組成的二維結構,節點元素散列在數組上,如果發生hash碰撞則使用鏈表串聯在數組節點上。

        Hash的內部結構

 

3.2 Hash使用的數據編碼

  hash 對象保存的鍵值對內的鍵和值字元串長度小於一定值及鍵值對。

 

3.3 使用場景

  (1) 存儲對象

 

4、Set(集合)

4.1 Set的內部結構

  Redis的set(集合)相當於Java語言里的HashSet,它內部的鍵值對是無序的、唯一的。它的內部實現了一個所有value為null的特殊字典。
集合中的最後一個元素被移除之後,數據結構被自動刪除,記憶體被回收。

        Set的內部結構

 

4.2 Set使用的數據編碼

  保存元素為整數及元素個數小於一定範圍使用 intset 編碼,任意條件不滿足,則使用 hashtable 編碼。

 

4.3 使用場景

  (1)標簽,社交,查詢有共同興趣愛好的人,智能推薦

  (2)抽獎

  (3)朋友圈點贊

 

5、Zset(有序集合)

5.1 Zset的內部結構

  zset(有序集合)是Redis中最常問的數據結構。它類似於Java語言中的SortedSet和HashMap的結合體,它一方面通過set來保證內部value值的唯一性,另一方面通過value的score(權重)來進行排序。這個排序的功能是通過Skip List(跳躍列表)來實現的。zset(有序集合)的最後一個元素value被移除後,數據結構被自動刪除,記憶體被回收。

        Zset的內部結構

 

5.2 Zset使用的數據編碼

  zset 對象中保存的元素個數小於及成員長度小於一定值使用 ziplist 編碼,任意條件不滿足,則使用 skiplist 編碼。

 

5.3 使用場景

  (1)排名場景


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 通過這個示例,你將更深入地瞭解如何在實際業務中應用Flutter,以及如何運用不同的解決方案和技術來構建高效、穩定的應用。 ...
  • # el-autocomplete核心參數 可以實現非同步的數據拉取,從非同步返回的數據中,選擇需要的結果,並回顯到文本框中。 ## fetch-suggestions 回調列表,非同步的方式獲取數據列表,顯示在列表框中 ## @select 當選中某一項時,會觸發這個方法,將數據獲取到,這時,我們可以將 ...
  • # 核心原理 長鏈接轉為短鏈接的核心原理是: 將短鏈接與原始長鏈接做一個映射,訪問短鏈接的時候,通過重定向的方式轉到長鏈接。 # 應用場景 比如分享功能,查看分享信息的原始鏈接通常是很長的,直接發給用戶,體驗不是很好,這時候就可以將其映射為一個短鏈接再發給用戶。 又比如我們熟知的百度網盤分享文件,雖 ...
  • ##一、定義 **講一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建造者模式是一種創建型模式。** ##二、描述 **包含以下四個角色:** ![](https://img2023.cnblogs.com/blog/1780813/202305/1780813-202305 ...
  • 你想成為一名架構師,對嗎?別對我撒謊,我知道你想成為架構師。即使你不想,你還是想成為一名更好的開發者。否則,你就不會花時間閱讀這篇文章。 這種態度值得贊賞。畢竟,我們都希望在自己所從事的領域變得更好,即使不能稱為最好。我在這裡就是為了幫助你實現這一目標。 那麼,你如何成為一名架構師呢?當然是通過學習 ...
  • #### 本文為[李你幹嘛](https://www.cnblogs.com/liniganma)原創,轉載請註明出處:[Pybind11綁定C++抽象類(DLL介面)](https://www.cnblogs.com/liniganma/p/17666063.html) # 摘要 假設我們將DLL ...
  • 數據類型是編程中的重要概念。數據類型指定了變數值的大小和類型。 Go是靜態類型的,這意味著一旦變數類型被定義,它只能存儲該類型的數據。 Go有三種基本數據類型: - bool:表示布爾值,要麼是true,要麼是false。 - 數值型:表示整數類型、浮點數值和複數類型。 - string:表示字元串 ...
  • ### Java 8 的改進 - 速度更快 - 代碼更少(**Lambda表達式**) - 引入強大的**Stream API** - 便於並行 - 最大化減少空指針異常(**Optional**) - **Nashorn**引擎,允許在JVM上運行**js**應用 - **並行流**就是把一個內容 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...