日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

表达式类型的实现数据结构_Redis系列(九)底层数据结构之五种基础数据类型的实现...

發布時間:2025/4/16 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 表达式类型的实现数据结构_Redis系列(九)底层数据结构之五种基础数据类型的实现... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • 前言
  • 定義
  • 字符串對象
    • int
    • raw
    • embstr
    • 浮點數如何保存?
    • 編碼轉換條件
    • 總結
  • 列表對象
    • 總結
  • 集合對象
    • intset
    • hashtable
    • 總結
  • 有序集合對象
    • ziplist 編碼
    • skiplist 編碼
    • 總結
  • 散列對象
    • ziplist 編碼
    • hashtable 編碼
    • 總結
  • 全文總結
  • 參考文章
  • 聯系我

前言

Redis 已經是大家耳熟能詳的東西了,日常工作也都在使用,面試中也是高頻的會涉及到,那么我們對它究竟了解有多深刻呢?

我讀了幾本 Redis 相關的書籍,嘗試去了解它的具體實現,將一些底層的數據結構及實現原理記錄下來。

本文將介紹 Redis 中 五種基礎數據類型 的實現方法。 這五種基本類型基本覆蓋了我們業務中使用的 80%的場景,對面試也覆蓋至少 90%.(其中重點當然是有序集合以及散列結構咯).

定義

在前面的八篇文章中,我們詳細的介紹了 Redis 中的 8 種基本數據結構,但是眾所周知,Redis 常用的數據類型有五種。包括,字符串,列表,集合,有序集合,哈希。

而這五種數據類型,底層就是用前面介紹的數據結構實現的,當然,并不是直接一對一的綁定關系,而是采用了精妙的設計,構建了一個對象系統。

熟悉 OOP 編程的讀者,可能很快就能想到為什么要這么設計了,對象系統帶來的好處是非常多的,但是并不在這一篇文章中講。這里只是提到對象系統,讓大家對于五種數據類型為什么可以用一些花里胡哨的方法來實現,有一個初步的了解。

接下來將逐一分析五種數據類型的底層實現數據結構,及實現方式(編碼)之間的切換條件。

注:后續提到五種數據類型,用 xx 對象來指代。比如 字符串對象,列表對象。提到的底層數據結構,用全稱來講。

字符串對象

涉及到的數據結構,SDS, 強烈建議閱讀本系列第一篇文章。

字符串對象的底層實現有三種可能:int, raw, embstr.

int

如果一個字符串對象,保存的值是一個整數值,并且這個整數值在 long 的范圍內,那么 redis 用整數值來保存這個信息,并且將字符串編碼設置為 int.

比如:

raw

如果字符串對象保存的是一個字符串, 并且長度大于 32 個字節,它就會使用前面講過的SDS(簡單動態字符串)數據結構來保存這個字符串值,并且將字符串對象的編碼設置為raw.

embstr

如果字符串對象保存的是一個字符串, 但是長度小于 32 個字節,它就會使用embstr來保存了,embstr編碼不是一個數據結構,而是對 SDS 的一個小優化,當使用 SDS 的時候,程序需要調用兩次內存分配,來給 字符串對象 和 SDS 各自分配一塊空間,而embstr只需要一次內存分配,因為他需要的空間很少,所以采用 連續的空間保存,即將 SDS 的值和 字符串對象的值放在一塊連續的內存空間上。這樣能在短字符串的時候提高一些效率。

比如:

浮點數如何保存?

redis 的字符串數據類型是支持保存浮點數,并且支持對浮點數進行加減操作,但是 redis 在底層是把浮點數轉換成字符串值,之后走上面三種編碼的規則的。對浮點數進行操作時,也是從字符串轉換成浮點數進行計算,然后再轉換成字符串進行保存的。

編碼轉換條件

這塊的知識其實是很符合我們的認知的,比如 int編碼只可以保存整數,那么當我們對一個 int 編碼的字符串對象,修改它的值,它自然就會使用 raw 編碼了。

但是有一個特性,Redis 沒有為embstr編碼提供任何的修改操作,這也就是為什么它只是個編碼而不是一個數據結構的原因。

所以在 Redis 中,embstr編碼的值其實是 只讀的,只要發生修改,立刻將編碼轉換成 raw.

總結

字符串對象底層的數據結構或者說編碼有三種,分別是 int, raw, embstr. 他們之間的使用條件如下:

編碼 | 使用條件 --- | --- int | 可以用 long 保存的整數 embstr | 字符串長度小于 32 字節(或者浮點數轉換后滿足) raw | 長度大于 32 的字符串

列表對象

涉及到的數據結構,壓縮列表, 雙向鏈表, 快速列表, 強烈建議閱讀本系列的第 二,三,四 篇文章。

在 Redis 3.2 版本之前,列表對象底層由 壓縮列表和雙向鏈表配合實現,當元素數量較少的時候,使用壓縮列表,當元素數量增多,就開始使用普通的雙向鏈表保存數據。

但是這種實現方式不夠好,雙向鏈表中的每個節點,都需要保存前后指針,這個內存的使用量 對于 Redis 這個內存數據庫來說極其不友好。

因此在 3.2 之后的版本,作者新實現了一個數據結構,叫做 quicklist. 所有列表的底層實現都是這個數據結構了。它的底層實現基本上就是將 雙向鏈表和壓縮列表進行了結合,用雙向的指針將壓縮列表進行連接,這樣不僅避免了壓縮列表存儲大量元素的性能壓力,同時避免了雙向鏈表連接指針占用空間過多的問題。

具體的原理講解請 閱讀對應的文章,這里不再贅述。

總結

編碼 | 使用條件 --- | --- quicklist | 所有數據

集合對象

涉及到的數據結構:intset, dict(hashtable), 強烈建議閱讀本系列第五,第六篇文章。

集合對象的編碼可以是 intset 或者 hashtable(字典) .

intset

當集合中的所有元素都是整數,且元素的數量不大于 512 個的時候,使用 intset 編碼。

intset 編碼時,底層使用 intset數據結構。

hashtable

當元素不符合全部為整數值且元素個數小于 512時,集合對象使用的編碼方式為 hashtable.

字典的每一個鍵都是一個字符串對象,其中保存了集合里的一個元素,字典的值全部被設置為 NULL.

總結

編碼 | 使用條件 --- | --- intset | 所有元素都是整數且元素個數小于 512 hashtable | 其他數據

有序集合對象

涉及到的數據結構,壓縮列表, 跳躍表, 字典, 強烈建議閱讀本系列 第三篇,第六篇,第七篇文章。

有序集合對象的編碼可以是 ziplist 以及skiplist.

ziplist 編碼

當使用 ziplist 編碼時,有序集合對象的實現數據結構為ziplist(聽起來像句廢話), 每個集合的元素 (key-value), 使用兩個緊挨著的壓縮列表的節點來表示,第一個節點保存集合元素的成員 (member), 第二個節點保存集合元素的分支 (score).

在壓縮列表的內部,集合元素按照分值從小到大進行排序。

skiplist 編碼

當使用 skiplist 編碼的時候,內部使用zset 來實現數據的保存,zset的定義如下:

typedef struct zset{zskiplist *zsl;dict *dict; }zset;

為什么需要同時使用跳躍表以及字典呢?

其實如果我們細想,單獨使用字典或者跳躍表,都是可以實現有序集合的所有功能的,但是性能太差勁了。

  • 當我們只使用字典來實現,我們可以以 O(1) 的時間復雜度獲取成員的分值,但是由于字典是無序的,當我們需要進行范圍性操作的時候,需要對字典中的所有元素進行排序,這個時間復雜度至少需要 O(nlogn).
  • 當我們只使用跳躍表來實現,我們可以在 O(logn) 的時間進行范圍排序操作,但是如果要獲取到某個元素的分值,時間復雜度也是 O(logn).

因此,將字典和跳躍表結合進行使用,可以在 O(1) 的時間復雜度下完成查詢分值操作,而對一些范圍操作,使用跳躍表可以達到 O(logn) 的是纏綿復雜度。

可以看到,我在上一次的例子中,添加了一個很長的 key 之后,有序集合的編碼方式就成為了skiplist.

總結

編碼 | 使用條件 --- | --- ziplist | 元素數量少于 128 且 所有元素成員的長度小于 64 字節 skiplist | 不滿足上述條件的其他情況

散列對象

涉及到的數據結構,壓縮列表, 字典, 強烈建議閱讀本系列 第三篇,第六篇文章。

哈希對象的編碼可以是ziplist或者hashtable.

ziplist 編碼

ziplist 編碼下的哈希對象,使用了壓縮列表作為底層實現數據結構,用兩個連續的壓縮列表節點來表示哈希對象中的一個鍵值對。實現方式類似于上面的有序集合的場景。

如圖中所示,當我放入了兩個簡單的鍵值對,此時哈希對象的編碼為 ziplist.

hashtable 編碼

這是對 hashtable 最直觀的應用了~

哈希結構本身在結構上和字典 (hashtable) 就頗為相似,因此哈希對象中的每一個鍵值對都是字典中的一個鍵值對。

  • 字典的每一個鍵都是一個字符串對象,對象中保存了鍵值對的鍵。
  • 字典的每一個值都是一個字符串對象,對象中保存了鍵值對的值。

如圖中所示,當我在上一個示例中額外加入一個很長的值,那么編碼方式就來到了hashtable.

總結

編碼 | 使用條件 --- | --- ziplist | 鍵值對的鍵和值的長度都小于 64 字節,且 鍵值對個數小于 512. hastable | 不滿足上述條件的其他條件

全文總結

其實在前面的幾篇文章寫完之后,也就是在所有的底層數據結構介紹完之后,所謂的Redis 的五種基礎數據類型的底層實現原理就已經沒有了難度。

所有用到的底層數據結構都知道了,剩下的無非是個排列組合問題以及各種實現方式之間的切換條件,然后這個條件也僅僅是了解性知識,強行記住也沒有必要。

這里把五種基礎數據類型的可能的編碼列出來方便理解及記憶。

基礎數據類型 | 可能的編碼方式 --- | --- 字符串 | int, raw, embstr 列表 | 之前是 ziplist 和 linkedlist, 現在全是 quicklist 了。 集合 | intset 或者 hashtable 有序集合 | ziplist 或者 skiplist, skiplist 編碼中使用了跳躍表+字典 散列 | ziplist 或者 hashtable

至于他們的轉換條件,如下:

參考文章

《Redis 的設計與實現(第二版)》

《Redis 深度歷險:核心原理和應用實踐》

完。

聯系我

最后,歡迎關注我的個人公眾號【 呼延十 】,會不定期更新很多后端工程師的學習筆記。 也歡迎直接公眾號私信或者郵箱聯系我,一定知無不言,言無不盡。

以上皆為個人所思所得,如有錯誤歡迎評論區指正。

歡迎轉載,煩請署名并保留原文鏈接。

聯系郵箱:huyanshi2580@gmail.com

更多學習筆記見個人博客或關注微信公眾號 < 呼延十 >------>呼延十

總結

以上是生活随笔為你收集整理的表达式类型的实现数据结构_Redis系列(九)底层数据结构之五种基础数据类型的实现...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩小说 | 亚洲瘦老头同性xxxxx | 欧美日韩激情一区二区 | 好色999| 亚洲播放 | 亚洲精品日韩欧美 | 欧美一区二区三区黄色 | 天天艹日日艹 | 深夜福利1000| 久久国产精品视频 | 四虎影视成人永久免费观看亚洲欧美 | 久久久久女人精品毛片九一 | 免费一级毛片麻豆精品 | 九九热在线视频免费观看 | 亚洲免费一级片 | 日韩一卡| 亚洲大尺度av | 一区二区在线 | 欧美一级久久久 | 午夜视频欧美 | 无码人妻丰满熟妇精品 | 亚洲无线看 | 日日噜噜夜夜狠狠久久丁香五月 | 一区二区三区日韩欧美 | 中文字幕在线播放 | 九色porny自拍视频在线播放 | 日本三级少妇 | 亚洲精品一区二区三区精华液 | 18女人毛片 | 日韩精品在线观看一区 | 亚洲视频在线观看一区二区三区 | jizz黄色片 | 日韩精品中文在线 | 九一国产在线观看 | 成人刺激视频 | 久久久夜 | 日本电影一区 | 怡红院成人网 | jizz日本在线播放 | 欧美三级自拍 | 欧美精品一区二区成人 | 亚洲精品综合久久 | 欧美国产视频一区 | 五月伊人网 | 日韩中文字幕有码 | 久操精品视频 | 黑人操日本女优 | 午夜资源 | 久久久看片| 亚洲国产成人一区二区精品区 | 超碰免费观看 | 久久精品视频1 | 老熟妻内射精品一区 | 久久久精品影视 | 中国av一级片 | 亚洲视频网 | 999精品在线视频 | 成人美女在线观看 | 国产高清精品一区二区三区 | 亚洲天堂日韩av | 欧美另类视频在线观看 | 亚洲天堂欧美 | 欧美交换国产一区内射 | 99极品视频| 成年视频在线 | 图书馆的女友动漫在线观看 | 天天综合在线观看 | 久久激情网站 | 欧美美女在线观看 | 一区二区毛片 | 日韩成人高清视频在线观看 | 午夜婷婷在线观看 | av中文字幕一区 | 亚洲啪 | 中文字幕精品久久 | www.四色| 成人无码久久久久毛片 | 久久亚洲AV成人无码一二三 | 国产麻豆一区 | 久久五月综合 | 欧美特级黄| 欧美一区二区国产 | 美足av电影 | 日韩色网站 | 用舌头去添高潮无码视频 | av在线小说 | 国产鲁鲁视频在线观看免费 | 婷婷中文在线 | 大香依人 | 亚洲经典一区二区三区四区 | 国产欧美日韩二区 | 亚洲久久视频 | 毛片无遮挡| 麻豆精品免费视频 | 国产一级自拍视频 | 2025国产精品视频 | 99成人在线 | 熟女人妻一区二区三区免费看 | 免费小视频在线观看 |