Redis 有5種基礎資料結構,分別為string(字串)、list(列表)、hash(字典)、set(集合)和zset(有序集合)。
1 String 結構
1.1 字串常用操作
SET key value //存入字串鍵值對 MSET key value [key value...] //批次儲存字串鍵值對 SETNX key value //存入一個不存在的字串鍵值對,如果已將存在,則set建立不成功,原來的值不變。 GET key //獲取一個字串鍵值 MGET key [key...] //批次獲取字串鍵值 DEL key [key...] //刪除一個健 EXPIRE key seconds //設定一個健的過期時間(秒)
1.2 原子操作
INCR key //將key所儲存的數字值加1--value值需要是整數,它的範圍在signed long 的最大值和最小值之間,超出範圍,會報錯。 DECR key //將key所儲存的數字值減1 INCRBY key increment //將key所儲存的值加上increment DECRby key decrement //將key所儲存的值減去decrement
2. String 應用場景
2.1 單值快取
SET key value GET key
2.2 物件快取
SET user:1 value(json格式資料)
2.3 分散式鎖
SETNX product:10001 true //返回1代表獲取鎖成功 SETNX product:10001 true //返回0代表獲取鎖失敗 ...執行業務操作 DEL product:10001 //執行完業務釋放鎖 SET product:10001 true ex 10 nx //防止程式意外終止導致死鎖
2.4 計數器
INCR article:readcount:{文章id}
GET article:readcount:{文章id}
2.5 分散式系統全域性序列號
INCRBY orderId 100 //redis批次生成序列號提升效能
3. Hash 結構
Redis的hash相當於Java裡面的HashMap,它是無序字典,內部儲存了很多鍵值對。
Hash 常用操作
HSET key field value // 儲存一個雜湊表key的鍵值 HSETNX key field value // 儲存一個不存在的雜湊表key的鍵值 HMSET key field value [field value...] //在一個雜湊表key中儲存多個鍵值對 HGET key field //獲取雜湊表key對應的field鍵值 HMGET key field [field...] //批次獲取雜湊表key中多個field鍵值 HDEL key field [field...] //刪除雜湊表key中的field鍵值 HLEN key //返回雜湊表key中field的數量 HGETALL key //返回雜湊表key中所有的鍵值 HINCRBY key field increment //為雜湊表key中field健的值加上增量increment
當hash移除了最後一個元素之後,該資料結構被自動刪除,記憶體資料被回收。
4 Hash 應用場景
4.1 物件快取
hash 結構可以用來儲存使用者資訊,與字串需要一次性全部序列化整個物件不同,hash可以對使用者結構中的每個欄位單獨儲存。這樣當我們需要獲取使用者資訊時,可以進行部分獲取。
// 例如記錄員工的資訊(userid、username、balance) HMSET user {userid}:name xiaoming {userid}:balance 30000 HMSET user 1:name xiaoming 1:balance 30000 HMGET user 1:name 1:balance
4.2 電商購物車
1)以使用者id為key;2)以商品id為field;3)以商品數量為value。
購物車操作(假設此時使用者的id為1001;商品id為10088)
1)新增商品--> hset cart:1001 10088 1
2)增加數量-->hincrby cart:1001
3) 商品總數-->hlen cart:1001
4)刪除商品-->hdel cart:1001 10088
5)獲取購物車所有商品-->hgetall cart:1001
5.List 結構
List常用操作
LPUSH key value [value...] //將一個或多個值value插入到key列表的表頭(最左邊) RPUSH key value [value...] //將一個或多個值value插入到key列表的表尾(最右邊) LPOP key //移除並返回key列表的頭元素 RPOP key //移除並返回key列表的尾元素 LRANGE key start stop //返回列表key中指定區間內的元素,區間以偏移量start和stop指定 BLPOP key [key...] timeout //從key列表表頭彈出一個元素,若列表中沒有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待 BRPOP key [key...] timeout //從key列表表尾彈出一個元素,若列表中沒有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
List 是連結串列而不是陣列。這意味著list的插入和刪除操作非常快,時間複雜度為O(1),但是索引定位很慢,時間複雜度為O(n)。
當列表彈出了最後一個元素之後,該資料結構被自動刪除,記憶體資料被回收。
6 List應用場景
列表結構常用來做非同步佇列使用。將需要延後處理的任務結構體序列化成字串,塞進Redis列表,另一個執行緒從這個列表種輪詢資料進行處理。
6.1 常用分散式資料結構
佇列是 先進先出 的資料結構,常用於訊息排隊和非同步邏輯處理,它會確保元素的訪問順序。
Queue(佇列) = LPUSH + RPOP
棧是 先進後出 的資料結構,跟佇列正好相反。
Stack(棧) = LPUSH + LPOP
Blocking MQ(阻塞佇列) = LPUSH + BRPOP
6.2 微博和微信公眾號訊息流
假如小明關注了Caoz,瘋狂賽車等大V
1)Caoz發微博,訊息ID為10018
LPUSH msg:{小明-id} 10018
2)瘋狂賽車發微博,訊息ID為10086
LPUSH msg:{小明-id} 10086
3)顯示最新的5條微博訊息
LRANGE msg:{小明-id} 0 4
7 Set 結構
set 相當於Java裡面的HashSet,它內部的鍵值對是無序的、唯一的。它的內部實現相當於一個特殊的字典,字典中所有的value都是一個值NULL。
當集合中最後一個元素被移除後,資料結構被自動刪除,記憶體被回收。
7.1 Set 常用操作
SADD key member [member...] //往集合key中存入元素,元素存在則忽略,若key不存在則新建 SREM key member [member...] //從集合key中刪除元素 SMEMBERS key //獲取集合key中所有元素 SCARD key //獲取集合key的元素個數 SISMEMBER key member //判斷member元素是否存在於集合key中 SRANDMEMBER key [count] //從集合key中隨機選出count個元素,元素不從key中刪除 SPOP key [count] //從集合key中隨機選出count個元素,元素從key中刪除
7.2 Set運算操作
SINTER key [key...] //交集運算 SINTERSTORE destination key [key...] //將交集結果存入新集合destination中 SUNION key [key...] //並集運算 SUNIONSTORE destination key [key...] //將並集結果存入新集合destination中 SDIFF key [key...] //差集運算 SDIFFSTORE destination key [key...] //將差集結果存入新集合destination中
8. Set 應用場景
8.1 微信抽獎小程式
1)點選參加抽獎進入集合
SADD key {userID} ----注意:此時key應替換為抽獎活動的ID
2)檢視參與抽獎所有使用者
SMEMBERS key
3)抽取count名中獎者
SRANDMEMBER key [count] /SPOP key [count]
8.2 微信微博點贊,收藏,標籤
1)點贊
SADD like:{訊息ID} {使用者ID}
2)取消點贊
SREM like:{訊息ID} {使用者ID}
3)檢查使用者是否點過贊
SISMEMBER like:{訊息ID} {使用者ID}
4)獲取點讚的使用者列表
SMEMBERS like:{訊息ID}
5)獲取點贊使用者數
SCARD like:{訊息ID}
8.3 透過集合操作 實現微博微信關注模型
1)諸葛老師關注的人:
zhugeSet-->{zhuangzhou,xushu}
2)樓蘭老師關注的人:
loulanSet-->{zhuge,zhouyu,zhuangzhou,xushu}
3)莊周老師關注的人:
zhuangzhouSet-->{zhuge,loulan,zhouyu,xushu,xunyu}
4)諸葛老師和樓蘭老師共同關注:
SINTER zhugeSet loulanSet -->{zhuanzhou,xushu}
5)我【諸葛老師】關注的人也關注他(樓蘭老師):【解析:我關注的就兩個人嘛 ,即zhuangzhou和xushu,那就去這兩個人的集合中,去判斷元素是否存在集合中唄】
SISMEMBER zhuangzhouSet loulan
SISMEMBER xushuSet loulan
6)我可能認識的人:
SDIFF loulanSet zhugeSet-->{zhuge,zhouyu}
9 ZSet 有序集合結構
zset 類似於Java中的SortedSet 和 HashMap的結合體,一方面它是一個set,保證了內部value的唯一性,另一方面,它可以給每個value賦予一個score,代表這個value的排序權重。
9.1 ZSet 常用操作
ZADD key score member [[score member]...] //往有序集合key中加入帶分值元素 ZREM key member [member...] //從有序集合key中刪除元素 ZSCORE key member //返回有序集合key中元素member的分值 ZINCBY key increment member //為有序集合key中元素member的分值加上increment ZCARD key //返回有序集合key中元素個數 ZRANGE key start stop [WITHSCORES] //正序獲取有序集合key從start下標到stop下標的元素 ZREVRANGE key start stop [WITHSCORES] //倒序獲取有序集合key從start下標到stop下標的元素
9.2 ZSet集合操作
ZUNIONSTORE destkey numkeys key [key] //並集計算 ZINTERSTORE destkey numkeys key [key] //交集計算
zset中最後一個value被移除後,資料結構被自動刪除,記憶體被回收。
10 ZSet 集合操作實現排行榜
1)點選新聞
ZINCRBY hotNews:20200819 1 XX釋出會
2)展示當日排行前十
ZREVRANGE hotNews:20200819 0 9 WITHSCORES
3)七日搜尋榜單計算
ZUNIONSTORE hotNews:20200813-20200819 7 hotNews:20200813 hotNews:20200814...hotNews:20200819
4)展示七日排行前十
ZREVRANGE hotNews:20200813-20200819 0 9 WITHSCORES
11 結構總結
如果想檢視key的結構型別,執行下面的命令
type keyname
如果想檢視key的儲存型別,例如,我知道了key是zset型別,但是我想知道它的儲存型別,是壓縮列表(ziplist),還是跳躍列表(skiplist),
可以執行下面的命令,進行檢視
object encoding keyname
12 容器型別資料結構的通用規則
list、set、hash、zset 這四種資料結構都是容器型別資料結構,他們共享下面兩條通用規則
1)create if not exists
如果容器不存在,就建立一個,再進行操作。
比如rpush操作剛開始是沒有列表的,Redis就會自動建立一個,然後再rpush進去新元素。
2)drop if not elements
如果容器裡的元素沒有了,那麼立即刪除容器,釋放記憶體。這意味著lpop操作到最後一個元素,列表就消失了。
學習參閱宣告
1.--【從原理到實戰(2023最新版)】
https://www.bilibili.com/video/BV1Gs4y1Q7Ls?p=6&vd_source=0e347fbc6c2b049143afaa5a15abfc1c
2.《Redis深度歷險--核心原理與應用實踐》