日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Redis常用数据类型的数据结构

發(fā)布時(shí)間:2024/7/5 81 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis常用数据类型的数据结构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. Redis 數(shù)據(jù)庫介紹
    • 2. 列表(list)
    • 3. 字典(hash)
    • 4. 集合(set)
    • 5. 有序集合(sortedset)
    • 6. 數(shù)據(jù)結(jié)構(gòu)持久化
    • 7. 總結(jié)

1. Redis 數(shù)據(jù)庫介紹

Redis 是一種鍵值Key-Value )數(shù)據(jù)庫。相對于關(guān)系型數(shù)據(jù)庫(比如MySQL),Redis也被叫作 非關(guān)系型 數(shù)據(jù)庫。

  • 像MySQL 這樣的關(guān)系型數(shù)據(jù)庫,表的結(jié)構(gòu)比較復(fù)雜,會(huì)包含很多字段,可以通過SQL語句,來實(shí)現(xiàn)非常復(fù)雜的查詢需求。
  • 而Redis中只包含“鍵”和“值”兩部分,只能通過“鍵”來查詢“值"。正是因?yàn)檫@樣簡單的存儲(chǔ)結(jié)構(gòu),讓Redis的讀寫效率非常高。
  • Redis 主要是作為內(nèi)存數(shù)據(jù)庫來使用,數(shù)據(jù)是存儲(chǔ)在內(nèi)存中的。它也支持將數(shù)據(jù)存儲(chǔ)在硬盤中。

Redis中,的數(shù)據(jù)類型是字符串的數(shù)據(jù)類型有很多,常用的分別是字符串列表、字典、集合有序集合。

“字符串(string)"這種數(shù)據(jù)類型非常簡單,對應(yīng)到數(shù)據(jù)結(jié)構(gòu)里,就是字符串。

2. 列表(list)

列表這種數(shù)據(jù)類型支持存儲(chǔ)一組數(shù)據(jù)。其對應(yīng)兩種實(shí)現(xiàn),一種是壓縮列表(ziplist),另一種是雙向循環(huán)鏈表

  • 列表中數(shù)據(jù)量比較小的時(shí)候,就可以采用壓縮列表的方式實(shí)現(xiàn)。具體需要同時(shí)滿足下面兩個(gè)條件:
  • 列表中保存的單個(gè)數(shù)據(jù)(有可能是字符串類型的)小于64字節(jié);
  • 列表中數(shù)據(jù)個(gè)數(shù)少于512個(gè)。
  • 壓縮列表,并不是基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),是Redis自己設(shè)計(jì)的一種數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)。它有點(diǎn)類似數(shù)組,通過一片連續(xù)的內(nèi)存,來存儲(chǔ)數(shù)據(jù)。它跟數(shù)組不同的一點(diǎn)是,它允許存儲(chǔ)的 數(shù)據(jù)大小不同 。存儲(chǔ)結(jié)構(gòu)如圖。

    壓縮列表中的“壓縮”如何理解?

    • 節(jié)省內(nèi)存,是相較于數(shù)組而言的。數(shù)組要求每個(gè)元素的大小相同,如果我們要存儲(chǔ)不同長度的字符串,就需要用最大長度的字符串大小作為元素的大小(假設(shè)是20個(gè)字節(jié))。當(dāng)我們存儲(chǔ)小于20個(gè)字節(jié)長度的字符串的時(shí)候,便會(huì)浪費(fèi)部分存儲(chǔ)空間。如圖。

    • 支持不同類型數(shù)據(jù)的存儲(chǔ)。因?yàn)閿?shù)據(jù)存儲(chǔ)在一片連續(xù)的內(nèi)存空間,通過鍵來獲取值為列表類型的數(shù)據(jù),讀取的效率也非常高。

    • 列表中數(shù)據(jù)量比較大的時(shí)候,也就不能同時(shí)滿足剛剛講的兩個(gè)條件,列表就要通過雙向循環(huán)鏈表來實(shí)現(xiàn)。

    Redis的雙向鏈表實(shí)現(xiàn)方式,非常值得借鑒。它額外定義一個(gè)list結(jié)構(gòu)體,來組織鏈表的首、尾指針,還有長度等信息。在使用的時(shí)候非常方便。

    // 以下是 C 語言代碼,因?yàn)?Redis 是用 C 語言實(shí)現(xiàn)的。 typedef struct listnode {struct listNode *prev;struct listNode *next;void *value; } listNode;typedef struct list {listNode *head;listNode *tail;unsigned long len;// .... 省略其他定義 } list;

    3. 字典(hash)

    字典類型用來存儲(chǔ)一組數(shù)據(jù)對。每個(gè)數(shù)據(jù)對又包含鍵值兩部分。字典類型也有兩種實(shí)現(xiàn)方式。

    • 一種是壓縮列表,另一種是散列表

    同樣,當(dāng)存儲(chǔ)數(shù)據(jù)量比較小的情況下,Redis 才使用壓縮列表來實(shí)現(xiàn)字典類型。需要滿足兩個(gè)條件:

    • 字典中保存的的大小都要小于64字節(jié)
    • 字典中鍵值對個(gè)數(shù)要小于512個(gè)。

    不能同時(shí)滿足上面兩個(gè)條件,Redis 就使用散列表來實(shí)現(xiàn)字典類型。

    • Redis使用 MurmurHash2 這種運(yùn)行速度快、隨機(jī)性好的哈希算法作為哈希函數(shù)。對于哈希沖突,Redis 使用鏈表法來解決。

    • Redis還支持散列表的動(dòng)態(tài)擴(kuò)容縮容。當(dāng)裝載因子 >1 時(shí),Redis會(huì)觸發(fā)擴(kuò)容,將散列表擴(kuò)大為原來的2倍左右(具體值需要計(jì)算得到,感興趣,可以閱讀源碼)。

    • 當(dāng)裝載因子 < 0.1 的時(shí)候,Redis 就會(huì)觸發(fā)縮容,縮小為字典中數(shù)據(jù)個(gè)數(shù)的大約2倍(這個(gè)值也是計(jì)算得到的)。

    擴(kuò)容縮容要做大量的數(shù)據(jù)搬移和哈希值的重新計(jì)算,所以比較耗時(shí)。Redis 使用漸進(jìn)式擴(kuò)容縮容策略,將數(shù)據(jù)搬移分批進(jìn)行避免大量數(shù)據(jù)一次性搬移導(dǎo)致的服務(wù)停頓。

    4. 集合(set)

    集合用來存儲(chǔ)一組不重復(fù)的數(shù)據(jù)。有兩種實(shí)現(xiàn)方法,一是基于有序數(shù)組,另一種基于散列表

    • 當(dāng)要存儲(chǔ)的數(shù)據(jù),同時(shí)滿足下面這樣兩個(gè)條件的時(shí)候,Redis 就采用有序數(shù)組,來實(shí)現(xiàn)集合。
  • 存儲(chǔ)的數(shù)據(jù)都是整數(shù)
  • 存儲(chǔ)的數(shù)據(jù)元素個(gè)數(shù)不超過512個(gè)。
    • 不能同時(shí)滿足這兩個(gè)條件時(shí),Redis 使用散列表來存儲(chǔ)集合中的數(shù)據(jù)。

    5. 有序集合(sortedset)

    有序集合用來存儲(chǔ)一組數(shù)據(jù),并且每個(gè)數(shù)據(jù)會(huì)附帶一個(gè)得分。通過得分大小,將數(shù)據(jù)組織成跳表這樣的數(shù)據(jù)結(jié)構(gòu),以支持快速地按照得分值得分區(qū)間獲取數(shù)據(jù)。

    當(dāng)數(shù)據(jù)量比較小時(shí),Redis會(huì)用壓縮列表來實(shí)現(xiàn)有序集合。前提有兩個(gè):

  • 所有數(shù)據(jù)的大小 小于64字節(jié)
  • 元素個(gè)數(shù)要小于128個(gè)。
  • 6. 數(shù)據(jù)結(jié)構(gòu)持久化

    盡管Redis經(jīng)常會(huì)被用作內(nèi)存數(shù)據(jù)庫,但它也支持?jǐn)?shù)據(jù)落盤,當(dāng)機(jī)器斷電時(shí),存儲(chǔ)在Redis中的數(shù)據(jù)不會(huì)丟。重啟后,Redis 只需再將存儲(chǔ)在硬盤中的數(shù)據(jù),重新讀到內(nèi)存,就可以繼續(xù)工作了。

    持久化”,可以籠統(tǒng)地可以理解為“存儲(chǔ)到磁盤"。如何持久化到硬盤?

  • 清除原有的存儲(chǔ)結(jié)構(gòu)只將數(shù)據(jù)存到磁盤。當(dāng)需要從磁盤還原數(shù)據(jù)到內(nèi)存時(shí),再重新將數(shù)據(jù)組織成原來的數(shù)據(jù)結(jié)構(gòu)。Redis采用的就是這種持久化思路。
    這種方式也有一定的弊端。那就是數(shù)據(jù)從硬盤還原到內(nèi)存的過程,會(huì)耗用較多時(shí)間
    比如,將散列表中的數(shù)據(jù)存儲(chǔ)到磁盤。當(dāng)我們從磁盤中,取出數(shù)據(jù)重新構(gòu)建散列表的時(shí)候,需要重新計(jì)算每個(gè)數(shù)據(jù)的哈希值。
  • 保留原來的存儲(chǔ)格式按照原有的格式存儲(chǔ)在磁盤中。拿散列表來舉例。可以將散列表的大小、每個(gè)數(shù)據(jù)被散列到的槽的編號(hào)等信息,都保存在磁盤中。有了這些信息,從磁盤還原到內(nèi)存的時(shí)候,就可以避免重新計(jì)算哈希值。
  • 7. 總結(jié)

    壓縮列表(可以看作一種特殊的數(shù)組)、有序數(shù)組、鏈表、散列表、跳表。實(shí)際上,Redis就是這些常用數(shù)據(jù)結(jié)構(gòu)的封裝。

    夯實(shí)基礎(chǔ)很重要?;A(chǔ)很好,不但能知其然,還能知其所以然,從而真正理解Redis作者設(shè)計(jì)的動(dòng)機(jī)。不但能有助于我們理解所用的開源軟件,還能為我們自己創(chuàng)新添磚加瓦。

    總結(jié)

    以上是生活随笔為你收集整理的Redis常用数据类型的数据结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。