共計 5961 個字符,預計需要花費 15 分鐘才能閱讀完成。
本篇內容主要講解“常見 Redis 數據結構有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“常見 Redis 數據結構有哪些”吧!
什么是數據結構?
有 Java 基礎的應該知道常用的一些數據結構,比如數組、隊列、棧等等 … 那 Redis 的數據結構跟 Java 的數據結構有什么區別嗎?答案是有的,如果一些小伙伴了解的 Map 的話就知道 Map 中有一個 Key 值和一個 Value 值,Redis 的數據結構也是這樣的。
Redis 的數據結構:String、List、Hash、Set 的話都是有一個 Key 值和一個 Value 值。
Key 值是名字,Value 值就是數據。這兩個是綁定在一起的,一個 Key 值對應一個 Value 值,我們稱之這樣的為鍵值對。
Redis 常用的基本命令
在 Redis 中,在不同的場景下會使用不同的命令。但是不是每個命令都需要記住呢?不是的,只需要熟悉最常用的命令就好了,在需要使用一些少用的命令可以去官方文檔查閱即可。下面來介紹 Redis 中一些常用的命令。
1.# exists(判斷 key 值是否存在):如果存在返回 1,反之返回 0
例子: exists name(name 為 key)
2.# del(刪除 key): 刪除成功返回 1,反之返回 0
3.# type(判斷 key 的類型)4.ttl(查看 key 存活時間
想學習更多命令可以自行到中文文檔進行查詢:http://www.redis.cn/
String 類型的介紹與使用場景
String 字符串類型是 Redis 中最基本的數據類型,在 Redis 中的應用場景很廣,一個 key 對應一個 value。
Redis 的 String 是動態字符串,可修改的字符串,它的內部結構類似于 Java 的 ArrayList, 采用預分配冗余空間的方式來減少內存的分配。
String 類型是二進制安全的,意思就是 Redis 的 String 可以包含任何的數據。如:數字,字符串,圖片等
String 類型的應用場景:驗證碼、計數器、訂單重復提交、用戶登錄信息、商品詳情的實現
String 的常用命令
1.# set/get 設置和獲取 key-value 注意中間一定要加空格
例子: set xxx(key) xxx(value)
get xxx(key)
2.# mget/mset 批量設置或獲取多個 key 的值
mset user:name jack user:age 2
mget user:name user:age
3.# incr incr 對 key 對應的值進行加 1 操作,并返回新的值
incr video:uv:1
4. # incrby 將 key 對應的數字加 increment. 如果 key 不存在,操作之前,key 就會被置為 0
incrby video:uv:1 10
5.# setex 設置 key 對應字符串 value,并且設置 key 在給定的 seconds 時間之后超時過期操作
setex code 20 778899 (設置一個 key 為 code value 為 778899 20 秒后過期)4
6. # setnx 將 key 設置值為 value,如果存在該 key 那么什么都不做,如果不存在 key 那么等同于 set 命令
setnx name xdclass.net
7. # getset 設置 key 的值,并返回 key 舊的值
get name uuuuu (這時會返回 xdclass.net,重新在 get 一下會獲得重新設置的值 uuuuu)
注意:值的長度不能超過 512MB,遵循 key 的命名規范:業務名:表明:ID(不要過長,用冒號分割)
String 的內部結構(內部結構為深入探究)
Redis 中沒有使用 C 語言的傳統字符串來表示,而是構建了一種名為簡單動態字符串(SDS)的抽象類型。為什么 Redis 要用自己構建的 SDS 而不是直接用 C 語言的 String 呢?原因其實很簡單,就是為了提升 Redis 操作的性能。
SDS 字符串與 C 語言字符串具有什么優勢?
常數復雜度獲取字符串長度:C 語言想獲取長度,那么它必須要遍歷一整個字符串才行。SDS 通過 len 屬性獲取 SDS 字符串長度的時間復雜度從 O(N) 變成了 O(1),保證了獲取字符串長度時不會成為 Redis 的性能瓶頸。
減少修改帶來的內存重新分配次數:內存重分配就是說在修改字符串時,由于內存空間的不足或者是超出了,需要對執行內存的重分配操作,這種操作由于會涉及到內存,所以導致時間的成本高,所以我們應該盡量的避免內存重分配。而在 SDS 就是有 len 和 free 這兩個屬性,可以使用優化策略來減少對內存重分配次數。
List 類型的介紹與使用場景
List 類型說白了就是一個鏈表,插入元素進去后是有序排列的,value 值是可以重復的,可以通過對應的下標獲取對應的 value 值,鏈表的左右兩邊都能進行插入和刪除數據。在插入時,如果該鍵并不存在,那么 Redis 將為該鍵創建一個新的鏈表。與此相反,如果這個鏈表中的所有元素都被刪除,那么該鍵也會被刪除掉。
應用場景:簡單隊列、最新評論列表、非實時排行榜:定時計算榜單,如手機日銷榜單
List 的常用命令
1. # lpush 將一個或多個值插入到列表頭部
lpush phone:rank:daily iphone6
2. # rpop 移除并獲取列表的最后一個元素
rpor phone:rank:daily
3. # llen 獲取列表長度
llen phone:rank:daily
4. # lrange 獲取 key 對應的 list 的指定下標范圍元素,其中 0 表示列表的第一個元素,- 1 表示獲取列表的所有元素
lrange phone:rank:daily 0 -1
5. # rpush 在 key 對應的 list 尾部添加一個元素
rpush phone:rank:daily xiaodi
6. # lpop 從 key 對應的 List 的尾部刪除一個元素,并返回該元素
lpop phone:rank:daily
7. # bropo 移出并獲取列表的最后一個元素,如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止
brpop phone:rank:daily 20
8. # lrem 移除元素
lrem phone:rank:daily 2 a
List 的內部結構(內部結構為深入探究)
上面了解了 List 的常用命令的使用,我們現在就來看下 list 的底層結構。
List 有兩種實現方式
壓縮鏈表 (ziplist):是 Redis 為了節省內存空間而開發的,它是特殊編碼的連續內存塊而組成的一個順序數據結構,一個壓縮列表 可以包含許多任意的節點,它的重點是內存連續!
雙端鏈表:使用 prev 和 next 這兩個指針,是可以從前向后也可以從后向前來實現 lpush 和 rpush 這些指令。因為是鏈表,所以也導致了 lindex 指令獲取某個元素需要遍歷鏈表才能獲取得到。時間復雜度 O(n)。
當列表的對象同時滿足下述兩個條件時,列表對象采用壓縮鏈表編碼:
(1)列表對象保存的所有元素長度都小于 64 個字節;
(2)列表元素所保存的元素個數小于 512 個
在 Redis3.2 之后,采用的是快速鏈表 -quicklist。quicklist 是一個雙向鏈表,并且它還是一個有 ziplist 特性的雙向鏈表,就是說 quicklist 每個節點都是 ziplist。這個快速鏈表結合了兩者的優點。
Hash 類型的介紹與使用場景
Redis 中的 Hash 類型是一個 String 類型的 field 和 value 的映射表,Hash 特別適合用于存儲對象,Hash 類似于 Map 結構。因為在 Redis 里,Hash 又是另外的一種鍵值對結構,而 Redis 本身就是 key-value 類型,所以這個 Hash 結構是套在了 Redis 下的 value 里。
下面說說 Hash 的底層數據結構:
一種是 ziplist,當存儲的數據超過所配置的數量大小時就是轉成 Hashtable 這種結構。這種轉換會比較消耗性能,所以盡量少用這種轉換操作。
另一種就是 hashtable,這種結構的時間復雜度為 O(1),但是會比較消耗內存空間。
對于 Hash 在 Redis 中的應用場景:購物車、用戶個人信息、商品詳情的實現
Hash 的常用命令
1. # hset 設置 key 指定的哈希集指定字段的值
hset product:detail:1 title iphone11
2. # hget 返回 key 指定的哈希集中該字段所關聯的值
hget product:detail:1 title
3. # hgetall 返回 key 指定的哈希集中所有的字段和值
hegetall product:detail:1
4. # hdel 從 key 指定的哈希集中移除指定的域
hdel product:detail:1 title
5. # hexists 返回 hash 里面的 field 是否存在
hexists product:detail:1 title (存在返回 1,不存在返回 0)
6. # hincrby 增加 key 指定的哈希集中的指定字段的數值,如果是 - 1 則是遞減
hincrby product:detail:1 key 1 (對 key 里的 value 值進行遞增或遞減)
7. # hmset 設置 key 指定的哈希集中指定字段的值
hmset product:detail:2 title xiaomi price 1000 stock 10
8. # hmget 返回 key 指定的哈希集中指定字段的值
hmget product:detail:2 title price
注意:每個 Hash 可以存儲 232- 1 鍵值對
Set 類型的介紹與使用場景
Redis 中的 Set 類型是一個集合,集合的概念是一堆不重復的組合。利用 Redis 提供的 Set 數據結構可以存儲一些集合性的數據。因為 Redis 很友好的為集合提供了求集、并集、差集等操作 (PS: 不懂的同學可以問下以前的數學老師哦~ 哈哈哈哈),那么就可以非常方便的實現共同關注、共同喜好等功能。對上面的集合操作,你還可以使用不同的命令選擇獎結果返回給客戶端還是存集合到一個新的集合中。
Redis 中 Set 應用場景:去重、社交應用關注(粉絲,共同好友)、統計網站 PV(UV、IP)大數據里面的用戶畫像標簽集合
Set 的常用命令
1. # sadd 添加一個或多個指定的元素到集合中,如果指定的元素已經在集合 key 中則忽略
sadd user:tags female
sadd user:tags bmw
2. # scard 返回集合存儲的 key 的基數(集合元素的數量) scard user:tags
3. # sdiff 返回的集合元素是第一個 key 集合與后面所有 key 集合的差集
sdiff user:tags:1 user:tags:2
4. # sinter 返回指定所有的集合的成員的交集
sinter user:tags:1 user:tags:2
5. # sismember 返回成員是否有存儲的集合 key 的成員
sismember user:tags:1 bmw
6. # srem 在集合中移除指定的元素,如果指定元素不是 key 集合中的則忽略
srem user:tags:1 bmw
7. # sunion 返回給定的多個集合的并集所有的成員
sunion user:tags:1 user:tags:2
SortedSet 類型的介紹與使用場景
和 Set 相比,SortedSet 是將 Set 中的元素增加了一個權重參數 score,使得集合中的元素能夠按 score 進行有序排序,比如存儲一個存儲班上同學成績的 SortedSet 集合,該集合 value 可以設為同學的學號,然而 score 就可以是考試成績。這樣才插入數據的時候,就已經為數據進行了排序。另外,SortedSet 還可以用來做帶權重的隊列。
應用場景:實時排行榜、優先級任務(隊列)、朋友圈(文章)點贊 - 取消
SortedSet 中跳躍表的介紹
跳躍表實則是一個鏈表,在傳統的鏈表中想要查找一個元素就要從最原始的地方開始查找,直到查找到該元素。在跳躍表中呢,它會把鏈表進行抽層,抽層的時候會隔幾個元素分為一個節點,抽層之后也是一條鏈表,節點會變少了。如下圖所示,當要尋找元素 78 時,如果是尋常的鏈表就會從左往右挨個查詢,這時查詢了 8 次才能找帶該元素。當使用跳躍表后,從第二層的開始出發,當查詢到 79 這個節點時發現沒有 78,則返回到 57 這個節點再返回第一層去尋找該元素。
SortedSet 的常用命令
1.# zadd 向有序集合里添加一個或者多個成員,或者更新已存在成員的分數
zadd video:rank 90 springcloud
zadd video:rank 80 springboot
zadd video:rank 50 redis
2.# zcard 獲取有序集合的成員數
zcard video:rank
3.# zcount 計算在有序集合中指定的區間分數的成員數
zcount video:rank 0 60
4.# zincrby 在有序集合中對指定成員的分數加上增量
zincrby video:rank 2 springcloud
5.# zrange 通過索引區間返回有序集合指定內的成員,成員位置分數按(從小到大排序) zrange voideo:rank 0 -1
zrange voideo:rank 0 -1 withscores(返回分數)
6.# zrevrange 通過索引集合中指定成員的排名,其中有序集合成員按 score 值遞增(從大到小排序) zrevrange voideo:rank 0 -1
7.# zrevrank 返回有序集合中指定的成員排名,有序集合成員按分數遞減(從大到小排序) zrevrank voideo:rank springcloud
8.# zrank 返回有序集 key 中成員 member 的排名,其中有序集成員按 score 值遞增(從小到大排序) zrank voideo:rank
9.# zrem 移除有序集合中的一個或者多個成員
zrem voideo:rank redis
10.# zscore 返回有序集合中的成員分數值
zscore voideo:rank springcloud
到此,相信大家對“常見 Redis 數據結構有哪些”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!