Redis常用六種數(shù)據(jù)類型
Redis 支持多種數(shù)據(jù)類型,每種類型都具有不同的特性和用途。以下是 Redis 中常見的數(shù)據(jù)類型:
一、字符串(String)
1、基本介紹
字符串是最基本的數(shù)據(jù)類型,可以存儲任意類型的數(shù)據(jù),如文本、數(shù)字或序列化對象??梢允褂米址嚓P(guān)的命令對其進行操作,如設(shè)置值(SET)、獲取值(GET)、增加數(shù)值(INCR)、追加字符串(APPEND)等。
2、底層數(shù)據(jù)結(jié)構(gòu)和原理
在 Redis 中,字符串類型的底層數(shù)據(jù)結(jié)構(gòu)和原理是簡單動態(tài)字符串(SDS,Simple Dynamic String)。
簡單動態(tài)字符串是 Redis 自己實現(xiàn)的一種字符串結(jié)構(gòu),相比于傳統(tǒng)的 C 字符串(以空字符 ‘\0’ 結(jié)尾的字符數(shù)組),簡單動態(tài)字符串具有以下優(yōu)勢:
-
O(1) 時間復(fù)雜度的修改操作:簡單動態(tài)字符串通過維護字符串長度和可用空間的變量,可以在 O(1) 時間復(fù)雜度內(nèi)進行字符串的修改操作,而不需要像傳統(tǒng) C 字符串那樣進行內(nèi)存拷貝和分配。
-
動態(tài)擴容和縮容:簡單動態(tài)字符串在需要擴容時,可以按需動態(tài)地增加內(nèi)存空間,而不是事先分配固定大小的緩沖區(qū)。這種動態(tài)擴容的機制使得字符串的長度可以根據(jù)需要進行自由調(diào)整,節(jié)省了內(nèi)存空間。
-
二進制安全:簡單動態(tài)字符串可以存儲任意二進制數(shù)據(jù),不僅僅限于文本字符串。這使得 Redis 可以在字符串類型中存儲和處理二進制數(shù)據(jù),而不會受到 C 字符串的限制。
-
內(nèi)存預(yù)分配和惰性空間釋放:簡單動態(tài)字符串在進行擴容時,會預(yù)先分配一定的額外空間,以減少頻繁的內(nèi)存分配操作。同時,在字符串縮短時,不會立即釋放多余的空間,而是保留一部分空間,以備后續(xù)使用,從而提高了性能。
總之,簡單動態(tài)字符串是 Redis 中字符串類型的底層數(shù)據(jù)結(jié)構(gòu),通過動態(tài)擴容和縮容、O(1) 時間復(fù)雜度的修改操作等特性,提供了高效的字符串操作。這種數(shù)據(jù)結(jié)構(gòu)使得 Redis 的字符串類型非常適用于存儲和處理各種類型的數(shù)據(jù),包括文本和二進制數(shù)據(jù)。
這個其實和Java中的ArrayList的實現(xiàn)比較像,ArrayList使用的是動態(tài)數(shù)組。如果讀者比較感興趣的話,后續(xù)我可以單獨寫一篇文章來著重講述兩者的區(qū)別。
二、哈希(Hash)
1、基本介紹
哈希是一種鍵值對集合,類似于對象或字典。每個哈希可以存儲多個字段和對應(yīng)的值??梢允褂霉O嚓P(guān)的命令對其進行操作,如設(shè)置**字段值(HSET)、獲取字段值(HGET)、獲取全部字段和值(HGETALL)**等。
2、底層數(shù)據(jù)結(jié)構(gòu)和原理
在 Redis 中,Hash(哈希)的底層數(shù)據(jù)結(jié)構(gòu)是哈希表(Hash Table)。
哈希表是一種基于鍵值對的數(shù)據(jù)結(jié)構(gòu),通過哈希函數(shù)將鍵映射到存儲位置,實現(xiàn)了高效的鍵值查找和插入操作。在 Redis 的哈希中,哈希表被用來存儲哈希的鍵值對。
Hash大家應(yīng)該都比較熟悉了,這里簡單講一下Redis 中哈希底層數(shù)據(jù)結(jié)構(gòu)和原理的一些關(guān)鍵點:
-
哈希表優(yōu)勢:使用哈希表作為哈希的底層數(shù)據(jù)結(jié)構(gòu)有幾個優(yōu)勢。首先,通過哈希表,可以以常數(shù)時間復(fù)雜度 O(1) 來執(zhí)行插入、刪除和查找操作。其次,哈希表可以高效地處理大量的鍵值對數(shù)據(jù),具有良好的擴展性。
-
哈希表存儲鍵值對:在 Redis 中,每對哈希的鍵值對被存儲為哈希表的鍵值對。哈希表的鍵被稱為字段(field),而哈希表的值被稱為值(value)。通過哈希表的鍵,可以快速檢索和操作哈希中的鍵值對。
-
哈希表的鍵沖突處理:由于哈希函數(shù)的輸出空間有限,不同的鍵可能映射到相同的哈希表位置,這就是所謂的鍵沖突。為了解決鍵沖突,Redis 使用鏈地址法(Separate Chaining)來處理相同哈希值的鍵。具體來說,Redis 將具有相同哈希值的鍵值對放在同一個鏈表中,通過鏈表來存儲沖突的鍵值對。
-
哈希表的擴容和縮容:為了保持哈希表的高效性能,Redis 在哈希表達到一定負載因子時會自動進行擴容操作。擴容操作涉及重新計算哈希函數(shù)和重新分配空間,以便保持較低的鍵沖突率。同樣,當(dāng)哈希表的使用率較低時,Redis 會自動進行縮容操作,以節(jié)省內(nèi)存空間。
-
哈希的常用操作:Redis 提供了一系列命令來操作哈希,如添加字段和值(HSET)、獲取值(HGET)、刪除字段(HDEL)等。這些命令通過操作底層的哈希表來實現(xiàn)哈希的操作。
Redis 中的哈希數(shù)據(jù)類型通過使用哈希表作為底層數(shù)據(jù)結(jié)構(gòu),實現(xiàn)了高效的鍵值查找和插入操作。這種數(shù)據(jù)結(jié)構(gòu)使得 Redis 的哈希非常適用于存儲和操作具有鍵值對結(jié)構(gòu)的數(shù)據(jù),如用戶信息、配置信息等。
三、列表(List)
1、基本介紹
列表是一個有序的字符串元素集合,可以在列表的兩端進行插入或刪除操作。列表可以用作隊列或棧。您可以使用列表相關(guān)的命令對其進行操作,如插入元素到列表頭(LPUSH)、彈出列表尾部元素(RPOP)、獲取指定范圍的元素(LRANGE)等。
2、底層數(shù)據(jù)結(jié)構(gòu)和原理
在 Redis 中,List(列表)的底層數(shù)據(jù)結(jié)構(gòu)是雙向鏈表(doubly linked list)。(注:Java中的LinkedList底層也是雙向鏈表,可以對比學(xué)習(xí)。)
雙向鏈表是一種由多個節(jié)點組成的數(shù)據(jù)結(jié)構(gòu),每個節(jié)點包含一個值和兩個指針,分別指向前一個節(jié)點和后一個節(jié)點。在 Redis 中,每個列表都由一個雙向鏈表來實現(xiàn),列表的每個元素都存儲在一個節(jié)點中。
Redis 通過使用雙向鏈表作為列表的底層數(shù)據(jù)結(jié)構(gòu),實現(xiàn)了對列表的高效操作。以下是一些關(guān)于 Redis 列表底層數(shù)據(jù)結(jié)構(gòu)和原理的重要細節(jié):
-
雙向鏈表優(yōu)勢:使用雙向鏈表作為列表的底層數(shù)據(jù)結(jié)構(gòu)有幾個優(yōu)勢。首先,它允許在列表的兩端進行高效的插入和刪除操作,時間復(fù)雜度為 O(1)。其次,雙向鏈表可以按照順序遍歷和反向遍歷列表,使得在有序列表中執(zhí)行范圍操作非常高效。
-
列表的頭節(jié)點和尾節(jié)點:Redis 中的列表有一個特殊的頭節(jié)點和尾節(jié)點,分別表示列表的開頭和結(jié)尾。這些節(jié)點不包含實際的值,只是作為指示列表邊界的標(biāo)記。它們的存在使得在列表兩端執(zhí)行插入和刪除操作更加高效。
-
列表的節(jié)點結(jié)構(gòu):每個列表節(jié)點包含三個主要部分。第一個部分是前置節(jié)點指針,指向前一個節(jié)點;第二個部分是后置節(jié)點指針,指向后一個節(jié)點;第三個部分是值,存儲實際的列表元素。
-
列表的頭指針和尾指針:Redis 中的列表有兩個指針,分別指向列表的頭節(jié)點和尾節(jié)點。這些指針使得在列表兩端執(zhí)行插入、刪除和訪問操作更加方便和高效。
-
列表的常用操作:Redis 提供了一系列命令來操作列表,如插入元素到列表頭部(LPUSH)、插入元素到列表尾部(RPUSH)、從列表頭部彈出元素(LPOP)、從列表尾部彈出元素(RPOP)等。這些命令通過操作雙向鏈表的節(jié)點來實現(xiàn)列表的操作。
Redis 中的列表數(shù)據(jù)類型通過使用雙向鏈表作為底層數(shù)據(jù)結(jié)構(gòu),實現(xiàn)了高效的插入、刪除和訪問操作。這種數(shù)據(jù)結(jié)構(gòu)使得 Redis 列表非常適用于隊列、棧、任務(wù)列表等應(yīng)用場景,同時提供了豐富的命令和操作來滿足不同的需求。
四、集合(Set)
1、基本介紹
集合是一組唯一的、無序的字符串元素集合。集合支持添加、刪除和判斷元素是否存在的操作。您可以使用集合相關(guān)的命令對其進行操作,如添加元素到集合(SADD)、刪除元素(SREM)、判斷元素是否存在(SISMEMBER)等。
2、底層數(shù)據(jù)結(jié)構(gòu)和原理
在 Redis 中,Set(集合)的底層數(shù)據(jù)結(jié)構(gòu)是哈希表(Hash Table)。
哈希表是一種基于鍵值對的數(shù)據(jù)結(jié)構(gòu),它通過哈希函數(shù)將鍵映射到存儲位置,從而實現(xiàn)高效的鍵值查找和插入操作。在 Redis 的集合中,哈希表被用來存儲集合的元素。
以下是 Redis 中集合底層數(shù)據(jù)結(jié)構(gòu)和原理的一些關(guān)鍵點:
-
哈希表優(yōu)勢:使用哈希表作為集合的底層數(shù)據(jù)結(jié)構(gòu)有幾個優(yōu)勢。首先,通過哈希表,可以以常數(shù)時間復(fù)雜度 O(1) 來執(zhí)行插入、刪除和查找操作。其次,哈希表可以高效地處理大量的鍵值對數(shù)據(jù),具有良好的擴展性。
-
哈希表存儲集合元素:在 Redis 中,每個集合元素被存儲為哈希表的鍵,而哈希表的值則被設(shè)置為一個固定的空占位符。通過哈希表的鍵,可以快速檢索和操作集合中的元素。
-
哈希表的鍵沖突處理:由于哈希函數(shù)的輸出空間有限,不同的鍵可能映射到相同的哈希表位置,這就是所謂的鍵沖突。為了解決鍵沖突,Redis 使用鏈地址法(Separate Chaining)來處理相同哈希值的鍵。具體來說,Redis 將具有相同哈希值的鍵放在同一個鏈表中,通過鏈表來存儲沖突的鍵值對。
-
哈希表的擴容和縮容:為了保持哈希表的高效性能,Redis 在哈希表達到一定負載因子時會自動進行擴容操作。擴容操作涉及重新計算哈希函數(shù)和重新分配空間,以便保持較低的鍵沖突率。同樣,當(dāng)哈希表的使用率較低時,Redis 會自動進行縮容操作,以節(jié)省內(nèi)存空間。
-
集合的常用操作:Redis 提供了一系列命令來操作集合,如添加元素到集合(SADD)、從集合中移除元素(SREM)、判斷元素是否存在于集合中(SISMEMBER)等。這些命令通過操作底層的哈希表來實現(xiàn)集合的操作。
Redis 中的集合數(shù)據(jù)類型通過使用哈希表作為底層數(shù)據(jù)結(jié)構(gòu),實現(xiàn)了高效的插入、刪除和查找操作。這種數(shù)據(jù)結(jié)構(gòu)使得 Redis 集合非常適用于存儲和操作唯一值的場景,并提供了豐富的命令和操作來滿足不同需求。
五、有序集合(Sorted Set)
1、基本介紹
有序集合是一種在集合基礎(chǔ)上增加了一個分?jǐn)?shù)(score)的數(shù)據(jù)結(jié)構(gòu)。每個元素都有一個唯一的值和一個對應(yīng)的分?jǐn)?shù),通過分?jǐn)?shù)可以對元素進行排序。您可以使用有序集合相關(guān)的命令對其進行操作,如添加元素到有序集合(ZADD)、根據(jù)分?jǐn)?shù)范圍獲取元素(ZRANGEBYSCORE)、獲取指定排名范圍的元素(ZRANGE)等。
2、底層數(shù)據(jù)結(jié)構(gòu)和原理
在 Redis 中,Sorted Set(有序集合)的底層數(shù)據(jù)結(jié)構(gòu)是跳躍表(Skip List)和哈希表(Hash Table)的結(jié)合使用。
跳躍表是一種有序數(shù)據(jù)結(jié)構(gòu),類似于鏈表,但在每個節(jié)點中添加了多個指向其他節(jié)點的指針,從而實現(xiàn)高效的查找和范圍操作。哈希表用于存儲每個成員及其對應(yīng)的分?jǐn)?shù)。
以下是 Redis 中有序集合底層數(shù)據(jù)結(jié)構(gòu)和原理的一些關(guān)鍵點:
-
跳躍表:有序集合使用跳躍表作為有序數(shù)據(jù)的主要存儲結(jié)構(gòu)。跳躍表中的每個節(jié)點都包含一個成員和一個分?jǐn)?shù),節(jié)點按照成員的字典序進行排序。通過多個層級的指針,跳躍表可以快速跳過一些節(jié)點,從而加快查找速度。
-
跳躍表的層級:跳躍表由多個層級組成,每個層級都是一個有序鏈表。最底層是包含所有成員的完整鏈表,而上層則是通過“跳躍”的方式連接較少的節(jié)點。這種層級結(jié)構(gòu)使得在跳躍表中查找成員的時間復(fù)雜度為 O(log n)。
-
哈希表:除了跳躍表,Redis 還使用哈希表來存儲每個成員及其對應(yīng)的分?jǐn)?shù)。哈希表通過將成員作為鍵、分?jǐn)?shù)作為值來存儲數(shù)據(jù)。這樣,當(dāng)需要根據(jù)成員進行查找或更新時,可以通過哈希表快速定位到對應(yīng)的節(jié)點。
-
跳躍表和哈希表的結(jié)合使用:通過將跳躍表和哈希表結(jié)合使用,Redis 實現(xiàn)了有序集合數(shù)據(jù)類型的高效操作。跳躍表提供了快速的有序查找和范圍操作,而哈希表則提供了快速定位成員的能力。
-
有序集合的常用操作:Redis 提供了一系列命令來操作有序集合,如添加成員和分?jǐn)?shù)(ZADD)、根據(jù)分?jǐn)?shù)范圍獲取成員(ZRANGEBYSCORE)、獲取成員的排名(ZRANK)等。這些命令通過操作底層的跳躍表和哈希表來實現(xiàn)有序集合的操作。
Redis 中的有序集合數(shù)據(jù)類型通過使用跳躍表和哈希表的結(jié)合,實現(xiàn)了高效的有序集合操作。跳躍表提供了快速的查找和范圍操作,而哈希表提供了快速定位成員的能力。這種數(shù)據(jù)結(jié)構(gòu)使得 Redis 有序集合非常適用于實現(xiàn)排行榜、計數(shù)器和范圍查詢等應(yīng)用場景。
六、Bitmaps
1、基本介紹
位圖是一種使用二進制位來存儲和操作數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。您可以使用位圖相關(guān)的命令對其進行操作,如設(shè)置位(SETBIT)、獲取位(GETBIT)、對多個位進行邏輯操作(BITOP)等。
除了以上常見的數(shù)據(jù)類型,Redis 還支持其他數(shù)據(jù)類型,如地理位置(Geospatial)、流(Stream)等。每種數(shù)據(jù)類型都有各自的用途和適用場景,您可以根據(jù)具體的需求選擇合適的數(shù)據(jù)類型來存儲和操作數(shù)據(jù)。
2、底層數(shù)據(jù)結(jié)構(gòu)和原理
在 Redis 中,Bitmaps(位圖)的底層數(shù)據(jù)結(jié)構(gòu)是字符串(String)。
字符串是 Redis 中最基本的數(shù)據(jù)結(jié)構(gòu),可以存儲二進制數(shù)據(jù)。在 Bitmaps 中,每個位(bit)都被存儲為字符串中的一個字符,可以表示為 0 或 1。Redis 使用字符串來表示位圖,并提供了一系列命令來操作位圖數(shù)據(jù)。
以下是 Redis 中位圖底層數(shù)據(jù)結(jié)構(gòu)和原理的一些關(guān)鍵點:
-
字符串存儲位:在 Redis 中,每個位都由一個字符來表示。位圖使用 0 或 1 來表示位的狀態(tài),通常使用字符 “0” 和 “1” 分別表示位值為 0 或 1。
-
字符串的位操作:Redis 提供了一些位操作命令,如設(shè)置位(SETBIT)、獲取位(GETBIT)、對多個位進行邏輯操作(BITOP)等。這些命令通過操作字符串的位來實現(xiàn)位圖的操作。
-
字符串的二進制存儲:Redis 使用字節(jié)序列來存儲字符串,每個字節(jié)可以表示 8 個位。位圖中的每個位會轉(zhuǎn)換成對應(yīng)字節(jié)中的某一位。
-
位圖的大?。篟edis 中的位圖可以非常大,可以有 2^32 = 4294967296 個位,即可以表示一個長度為 4294967296 的位序列。
-
位圖的應(yīng)用:位圖在 Redis 中廣泛應(yīng)用于各種場景,如統(tǒng)計在線用戶、記錄用戶行為、判斷某個元素是否存在等。由于位圖的存儲非常緊湊,可以有效地節(jié)省存儲空間。
請注意,位圖雖然非常高效,但它是以整個字符串作為單位進行操作的,如果只需要操作其中的某些位,可能會涉及到整個字符串的讀取和寫入,可能會對性能產(chǎn)生影響。因此,在使用位圖時,需要根據(jù)實際需求和數(shù)據(jù)規(guī)模進行權(quán)衡和設(shè)計。
除了以上常見的數(shù)據(jù)類型,Redis 還支持其他數(shù)據(jù)類型,如地理位置(Geospatial)、流(Stream)等。每種數(shù)據(jù)類型都有各自的用途和適用場景,可以根據(jù)具體的需求選擇合適的數(shù)據(jù)類型來存儲和操作數(shù)據(jù)。文章來源:http://www.zghlxwxcb.cn/news/detail-574753.html
歡迎關(guān)注我的公眾號,除了分享一些技術(shù)文章,還會分享一些工作經(jīng)驗和有趣的事。
文章來源地址http://www.zghlxwxcb.cn/news/detail-574753.html
到了這里,關(guān)于Redis常用數(shù)據(jù)結(jié)構(gòu)及原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!