redis中的常用5大數(shù)據(jù)類型
1、string(字符串)
String是Redis中最常用的一種數(shù)據(jù)類型,也是Redis中最簡單的一種數(shù)據(jù)類型。
首先,表面上它是字符串,但其實他可以靈活的表示字符串、整數(shù)、浮點數(shù)3種值。
Redis會自動的識別這3種值。
2、list(列表)
實際上是一個鏈表,before Node after , left,right 都可以插入值
- 如果key 不存在,創(chuàng)建新的鏈表
- 如果key存在,新增內(nèi)容
- 如果移除了所有值,空鏈表,也代表不存在!
在兩邊插入或者改動值,效率最高! 中間元素,相對來說效率會低一點~
消息排隊!消息隊列 (Lpush Rpop), 棧( Lpush Lpop)!
3、hash(哈希)
哈希的描述:
- 哈希是一種鍵值對存儲結(jié)構(gòu),它類似于關(guān)聯(lián)數(shù)組或字典。
- 在哈希中,每個鍵都唯一地對應(yīng)一個值,而值可以是字符串、數(shù)字或其他數(shù)據(jù)類型。
- 哈希適合存儲具有結(jié)構(gòu)化數(shù)據(jù)的對象,比如用戶信息、產(chǎn)品信息等。
- 在哈希中,可以對單個字段進(jìn)行讀寫操作,而不需要讀取整個數(shù)據(jù)結(jié)構(gòu)。
哈希的底層數(shù)據(jù)結(jié)構(gòu):
- 哈希的底層數(shù)據(jù)結(jié)構(gòu)是哈希表(Hash Table)。
- 在哈希表中,每個鍵值對被存儲在哈希表的一個桶(Bucket)中。
- 桶是一個數(shù)組,它的大小取決于哈希表的大小,通常會隨著元素的增加而動態(tài)調(diào)整。
- 哈希表通過哈希函數(shù)將鍵映射到桶的位置,并在桶中存儲鍵值對。
下面舉個例子:
當(dāng)你插入一條數(shù)據(jù)到哈希中時,它的存儲過程如下:
假設(shè)你要執(zhí)行以下命令將一條數(shù)據(jù)插入到哈希中:
HSET myhash field1 value1
- 計算哈希值:對鍵
myhash
進(jìn)行哈希運算,得到一個哈希值,該哈希值將確定數(shù)據(jù)在哈希表中的存儲位置。 - 映射到桶:根據(jù)計算得到的哈希值,確定數(shù)據(jù)存儲在哈希表的哪個桶中。
- 存儲鍵值對:在確定的桶中,存儲鍵值對數(shù)據(jù)
{field1: value1}
。
讓我們假設(shè)經(jīng)過哈希計算后,得到的哈希值為 0x12345678
,那么這條數(shù)據(jù)將存儲在哈希表中的桶 0x1234
中。
假設(shè)該桶中已經(jīng)有一些數(shù)據(jù)存在,哈希表和桶的存儲可能如下所示:
Hash Table: Bucket 0x1234: --> {field2: value2} --> {field1: value1} --> {field3: value3} --> {field4: value4} --> ... Bucket 0x5678: --> {field5: value5} --> ... Bucket ... --> ...
在這個示例中:
- 哈希表包含多個桶,每個桶存儲了一部分鍵值對數(shù)據(jù)。
- 桶
0x1234
中存儲了一些鍵值對數(shù)據(jù),其中包括{field1: value1}
。 - 這個桶可能使用鏈表等數(shù)據(jù)結(jié)構(gòu)來存儲數(shù)據(jù),以處理哈希沖突,確保每個鍵值對都可以被正確地存儲和檢索。
注意:
哈希和下面要介紹的set的底層數(shù)據(jù)結(jié)構(gòu)有點相似,但是哈希里面存儲的是鍵值對,偏向于鍵值對;set中偏向于值的集合。
4、set(集合)
集合的描述
- 集合是一種無序、唯一的數(shù)據(jù)結(jié)構(gòu),它類似于數(shù)學(xué)上的集合。
- 在集合中,每個元素都是唯一的,且無序存儲。
- 集合適合存儲不重復(fù)的元素,比如用戶的標(biāo)簽、商品的標(biāo)簽等。
- 集合支持添加、刪除、查詢等操作,可以對整個集合進(jìn)行操作,也可以對單個元素進(jìn)行操作。
集合(Set)的底層數(shù)據(jù)結(jié)構(gòu)可以有兩種形式:整數(shù)集合(IntSet)和哈希表(Hash Table)。
整數(shù)集合主要用于存儲數(shù)字類型的元素,而哈希表則用于存儲其他類型的元素或者大數(shù)量的元素。
整數(shù)集合(IntSet):
- 整數(shù)集合是一種特殊的數(shù)據(jù)結(jié)構(gòu),它專門用于存儲整數(shù)類型的元素。
- 整數(shù)集合采用緊湊的數(shù)組形式存儲元素,這樣可以節(jié)省內(nèi)存空間。
- 當(dāng)集合中的元素都是整數(shù)類型,并且數(shù)量較小時,Redis 會使用整數(shù)集合作為集合的底層數(shù)據(jù)結(jié)構(gòu)。
哈希表(Hash Table):
- 哈希表是一種通用的數(shù)據(jù)結(jié)構(gòu),它可以存儲任意類型的元素,并且支持動態(tài)擴(kuò)容。
- 當(dāng)集合中的元素包含了其他類型,或者數(shù)量較大時,Redis 會使用哈希表作為集合的底層數(shù)據(jù)結(jié)構(gòu)。
在插入數(shù)據(jù)時,底層數(shù)據(jù)結(jié)構(gòu)可能會發(fā)生變化,具體取決于當(dāng)前集合的類型和大?。?/p>
對于整數(shù)集合(IntSet):
- 如果集合中的元素都是整數(shù)類型,并且待插入的元素可以表示為整數(shù),則 Redis 將嘗試將元素添加到現(xiàn)有的整數(shù)集合中。
- 如果插入的元素?zé)o法表示為整數(shù),或者整數(shù)集合無法容納新的元素,Redis 將會將整數(shù)集合轉(zhuǎn)換為哈希表,然后將新的元素插入到哈希表中。
對于哈希表(Hash Table):
- 如果集合已經(jīng)使用哈希表作為底層數(shù)據(jù)結(jié)構(gòu),Redis 將直接將新的元素添加到哈希表中。
- 如果集合中的元素都是整數(shù)類型,但哈希表的性能更好(例如,集合數(shù)量較大),Redis 也會將整數(shù)集合轉(zhuǎn)換為哈希表,然后將新的元素插入到哈希表中。
當(dāng)插入非整數(shù)類型的元素到哈希表時,Redis 會通過一系列步驟將該元素插入到哈希表中。
下面是這個過程的簡要描述
- 計算哈希值:對于要插入的元素,Redis 首先會計算其哈希值,以確定在哈希表中的存儲位置。
- 映射到桶:根據(jù)計算得到的哈希值,Redis 確定了元素應(yīng)該存儲在哈希表的哪個桶中。
- 處理哈希沖突:由于不同的元素可能具有相同的哈希值,所以可能會發(fā)生哈希沖突。在這種情況下,Redis 會采取適當(dāng)?shù)姆椒▉斫鉀Q沖突,例如使用開放定址法、鏈地址法等。
- 存儲元素:一旦確定了存儲位置并解決了哈希沖突,Redis 就會在哈希表的相應(yīng)桶中存儲該元素。
開放定址法和鏈地址法是解決哈希沖突的兩種常見方法。
開放定址法:
- 在開放定址法中,當(dāng)發(fā)生哈希沖突時,不是將沖突的元素放入一個單獨的鏈表中,而是通過一系列的步驟在哈希表中尋找另一個空槽來存放沖突的元素。
- 具體的步驟包括線性探查、二次探查、雙重哈希等。例如,在線性探查中,如果發(fā)生沖突,就會依次檢查哈希表中的下一個位置,直到找到一個空槽。
- 開放定址法的優(yōu)點是節(jié)省了存儲空間,因為它不需要額外的鏈表來存儲沖突的元素。但是如果哈希表填滿了大部分槽位,性能會下降。
鏈地址法:
- 在鏈地址法中,哈希表的每個槽位都維護(hù)一個鏈表,用于存儲哈希值相同的元素。
- 當(dāng)發(fā)生哈希沖突時,新的元素將被插入到相應(yīng)槽位的鏈表中,而不是直接放入槽位中。
- 這樣,哈希表中的每個槽位都可能對應(yīng)著一個鏈表,鏈表中存儲了所有哈希值相同的元素。
- 鏈地址法的優(yōu)點是解決了哈希沖突,保證了元素的正確存儲和檢索。但是需要額外的空間來存儲鏈表,可能會占用更多的內(nèi)存。
總的來說,開放定址法通過不斷尋找空槽位來解決沖突,而鏈地址法通過維護(hù)鏈表來存儲沖突的元素。
5、zset(有序集合)
有序集合(Sorted Set,通常簡稱為 ZSET)是 Redis 中的一種數(shù)據(jù)結(jié)構(gòu),它類似于集合(SET),但每個成員都關(guān)聯(lián)了一個分?jǐn)?shù)(Score),從而實現(xiàn)了元素的有序存儲。
ZSET 的底層數(shù)據(jù)結(jié)構(gòu)主要由兩部分組成:跳躍表(Skip List)和哈希表(Hash Table)。
- 跳躍表(Skip List):跳躍表是一種隨機(jī)化數(shù)據(jù)結(jié)構(gòu),用于有序元素的快速查找和插入。它是通過在元素的層級之間建立索引來實現(xiàn)快速查找的。跳躍表中的每個節(jié)點都包含一個成員(Member)和一個分?jǐn)?shù)(Score),以及若干個指向其他節(jié)點的指針,這些指針用于在不同層級之間快速跳躍。通過跳躍表,ZSET 可以實現(xiàn)基于分?jǐn)?shù)的范圍查詢、快速的成員查找和插入操作。
- 哈希表(Hash Table):除了跳躍表外,ZSET 還使用了一個哈希表,用于存儲成員到分?jǐn)?shù)的映射關(guān)系。在哈希表中,鍵是成員,值是分?jǐn)?shù)。通過哈希表,可以快速地查找指定成員的分?jǐn)?shù),或者更新成員的分?jǐn)?shù)。哈希表使得 ZSET 可以在常數(shù)時間內(nèi)完成成員與分?jǐn)?shù)之間的映射操作,而不需要遍歷跳躍表。
讓我們來看一個示例,假設(shè)我們有一個 ZSET,存儲了一些成員及其對應(yīng)的分?jǐn)?shù)。
假設(shè)我們有以下 ZSET:
ZADD myzset 10 member1 ZADD myzset 20 member2 ZADD myzset 30 member3
在底層,這個 ZSET 的數(shù)據(jù)可能會被存儲如下:
跳躍表(Skip List):
Level 2: member3 ---------------> NULL Level 1: member2 -------> member3 Base Level: member1 -> member2 -> member3
在跳躍表中,每個節(jié)點包含成員和分?jǐn)?shù)信息,并且包含指向同一層級下一個節(jié)點的指針。
較高層級的節(jié)點包含更多的指針,以實現(xiàn)更快的跳躍。
哈希表(Hash Table):
Key: Value: member1 10 member2 20 member3 30
在哈希表中,鍵是成員,值是成員對應(yīng)的分?jǐn)?shù)。
通過哈希表,Redis 可以快速地查找成員對應(yīng)的分?jǐn)?shù),或者更新成員的分?jǐn)?shù)。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
spring?boot集成redis基礎(chǔ)入門實例詳解
redis在spring?boot項目開發(fā)中是常用的緩存套件,常見使用的是spring-boot-starter-data-redis,這篇文章主要介紹了spring?boot集成redis基礎(chǔ)入門,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10redis的底層數(shù)據(jù)結(jié)構(gòu)詳解
Redis性能高得益于其優(yōu)化的數(shù)據(jù)結(jié)構(gòu),Redis的數(shù)據(jù)結(jié)構(gòu)分為對外暴露的和內(nèi)部底層的兩種,對外暴露的數(shù)據(jù)結(jié)構(gòu)包括String、list、hash、set、zset等,而內(nèi)部底層的數(shù)據(jù)結(jié)構(gòu)則包括SDS、hashtable、ziplist、linkedlist、quicklist、intset、skiplist等2025-02-02使用redis-plus-plus庫連接redis的實現(xiàn)方法
本文主要介紹了使用redis-plus-plus庫連接redis的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02