redis是一個非常快速的非關係資料庫解決方案。其簡單的鍵值數據模型使 Redis 能夠處理大型數據集,同時保持令人印象深刻的讀寫速度和可用性。redis提供了五種數據類型,分別是是:1、string(字元串);2、hash(哈希);3、list(列表);4、set(集合);5、sort ... ...
前言
redis是一個非常快速的非關係資料庫解決方案。其簡單的鍵值數據模型使 Redis 能夠處理大型數據集,同時保持令人印象深刻的讀寫速度和可用性。redis提供了五種數據類型,分別是是:1、string(字元串);2、hash(哈希);3、list(列表);4、set(集合);5、sort set (有序集合)(其實隨著 Redis 版本的更新,後面又支持了四種數據類型:BitMap(2.2 版新增)、HyperLogLog(2.8 版新增)、GEO(3.2 版新增)、Stream(5.0 版新增),本文暫不作介紹。)。接下我就給大家介紹一下這五種數據類型的基本用法和使用場景。
一. String
1、簡介
字元串類型:實際上可以是字元串(包括XML、JSON)、還有數字(整形、浮點數)、二進位(圖片、音頻、視頻),最大不能超過512MB。
2、常用命令
(1)設值命令:
set age 23 ex 10 //10秒後過期 px 10000 毫秒過期
setnx name test //不存在鍵name時,返回1設置成功;存在的話失敗0
set age 25 xx //存在鍵age時,返回1成功
(2)獲值命令:
get age //存在則返回value, 不存在返回nil
(3)批量設值:
mset country china city beijing
(4)批量獲取:
mget country city address //返回china beigjin, address為nil
(5)計數命令:
incr age //必須為整數自加1,非整數返回錯誤,無age鍵從0自增返回1
decr age //整數age減1
incrby age 2 //整數age+2
decrby age 2//整數age -2
incrbyfloat score 1.1 //浮點型score+1.1
(6)append追加指令:
set name hello; append name world //追加後成helloworld
(7)字元串長度:
set hello “世界”;strlen hello//結果6,每個中文占3個位元組
(8)截取字元串:
set name helloworld ; getrange name 2 4//返回 llo
3、使用場景
(1) 簡單字元緩存
(2) 分散式鎖
(3)計數功能——》計數服務
INCR article:001 (文章001閱讀數加1)
GET airticle:001
(4) 各類場景下(單機或分散式)的標識號
Incrby serialNo 1 ——》分給每個服務1000個本地緩存Incrby serialNo 1000
(5) 集群環境下的Session共用
二、Hash
1、簡介
哈希hash是一個string類型的field和value的映射表,hash特適合用於存儲對象
2、常用命令
(1)設值命令:
設值:
hset user:1 name james //成功返回1,失敗返回0
批量設值:
hmset user:2 name james age 23 sex boy //返回OK
(2)取值命令:
取值:
hget user:1 name //返回james
批量取值:
hmget user:2 name age sex //返回三行:james 23 boy
(3)刪除命令:
hdel user:1 age //返回刪除的個數
(4)計算個數:
hset user:1 name james;
hset user:1 age 23;
hlen user:1 //返回2,user:1有兩個屬性值
(5)判斷field是否存在:
hexists user:2 name //若存在返回1,不存在返回0
(6)獲取所有field:
hkeys user:2 // 返回name age sex三個field
(7)獲取user:2所有value:
hvals user:2 // 返回james 23 boy
(8)獲取user:2所有field與value:
hgetall user:2 //name age sex james 23 boy值
(9)增加1:
hincrby user:2 age 1 //age+1
hincrbyfloat user:2 age 2 //浮點型加2
3 、使用場景
(1) 存儲對象
實例:購物車
Hmset cart:001 prod:01 1 prod:02 1
當前登錄用戶ID號為key,商品ID號為Field,加入購物車數量為value
三、 List
1、簡介
用來存儲多個有序的字元串,一個列表最多可存2的32次方減1個元素。因為有序,可以通過索引下標獲取元素或某個範圍內元素列表,列表元素可以重覆
2、常用命令
(1)添加命令:
rpush james c b a //從右向左插入cba, 返回值3
lrange james 0 -1 //從左到右獲取列表所有元素 返回 c b a
lpush key c b a //從左向右插入cba
linsert james before b teacher //在b之前插入teacher, after為之後,使 用lrange james 0 -1 查看:c teacher b a
(2)查找命令:
lrange key start end //索引下標特點:從左到右為0到N-1
lindex james -1 //返回最右末尾a,-2返回b
llen james //返回當前列表長度
lpop james //把最左邊的第一個元素c刪除
rpop james //把最右邊的元素a刪除
3、使用場景
(1)利用List實現棧、隊列
1.先進後出:棧 = LPUSH+LPOP->FILO
2.先進先出:隊列=LPUSH+RPOP
3.Blocking MQ(堵塞隊列)= LPUSH+BRPOP
(2)redis做消息隊列(不推薦使用redis做消息隊列)
下麵以訂單為例子進行演示:
- 每個用戶有多個訂單key為 order:1 order:2 order:3, 結合hmset
hmset order:1 orderId 1 money 36.6 time 2018-01-01
hmset order:2 orderId 2 money 38.6 time 2018-01-01
hmset order:3 orderId 3 money 39.6 time 2018-01-01
- 把訂單信息的key放到隊列
lpush user:1:order order:1 order:2 order:3
- 新產生了一個訂單order:4,
hmset order:4 orderId 4 money 40.6 time 2018-01-01
- 追加一個order:4放入隊列第一個位置
lpush user:1:order order:4
- 當需要查詢用戶訂單記錄時:
List orderKeys = lrange user:1:order 0 -1 //查詢user:1 的所有訂單key值
for(Order order: orderKeys){
hmget order:1
}
(3)列表緩存
小明微信號ID:001,他關註了頂級架構師、愛敲代碼的小黃、程式員蝸牛上圖的展示效果應該如何設計?
- 頂級架構師發佈了一條文章ID為100的文章
lpush:mes:001 100
- 愛敲代碼的小黃髮布了一條文章ID為101的文章
lpush:mes:001 101
- 程式員蝸牛發佈了一條文章ID為102的文章
lpush:mes:001 102
- 小明的微信訂閱號列表實現如下
lrange mes:001 0 5
四、Set
1、簡介
保存多元素,與列表不一樣的是不允許有重覆元素,且集合是無序,一個集合最多可存2的32次方減1個元素,除了支持增刪改查,還支持集合交集、並集、差集;
2、常用命令
(1)檢查user鍵值是否存在
exists user
(2)設置命令:
sadd user a b c//向user插入3個元素,返回3
sadd user a b //若再加入相同的元素,則重覆無效,返回0
(3)查找命令:
smember user //獲取user的所有元素,返回結果無序
(4)刪除命令:
srem user a //返回1,刪除a元素
(5)計算元素個數
scard user //返回2,計算元素個數
3、Set 集合特殊的操作指令
(1)集合與集合之間的交集
sinter setA setB -> 得到集合 {B,C}
(2)集合與集合之間的並集
sunion setA setB -->得到集合{A,B,C}
(3)集合與集合之間的差集
sdiff setA setB-->得到集合{A}
4、使用場景:
(1)標簽,社交,查詢有共同興趣愛好的人,智能推薦
使用方式:
給用戶添加標簽:
sadd user:1:fav basball fball pq
sadd user:2:fav basball fball
............
或給標簽添加用戶
sadd basball:users user:1 user:2
sadd fball:users user:1 user:2
........
計算出共同感興趣的人:
sinter user:1:fav user2:fav
(2)抽獎
微信有一個活動,活動ID為001,如何實現微信抽獎功能,基於Redis設計實現?
假設小明的userId為: 004
- 當小明點擊參與抽獎時,數據放入set集合
sadd active:001 004
- 開始抽獎2名中獎者(隨機)
srandmember active:001 2
或者
spop act:001 2
- 查看有多少用戶參加了本次抽獎
smembers active:001
(3)朋友圈點贊
朋友圈消息ID:008,微信點贊如何設計?
張三用戶ID 為userId:01
(1)張三對消息ID008點贊啦
sadd zan:008 userId:01
(2)張三取消了對消息008的點贊
srem zan:008 userId:01
(3)檢查用戶是否點過贊
sismember zan:008 userId:01
(4)獲取消息ID008所有的點贊用戶列表
smembers zan:008
(5)消息ID008的點贊數計算
scard zan:008
(4)Set集合特殊的操作指令應用場景
如何實現微博的微關係設計?
條件:
1 James關註的人
sadd jamesCares Irving,peter,king,jack
條件2 Irving關註的人
sadd IrvingCares james,jack,cjk,king
條件3 jack關註的人
sadd avCares deer,cjk,king
計算:
計算1 James和Irving共同關註的人
sinter jamesCares IrvingCares , 計算結果為 {jack, king}
計算2 我關註的人也關註他(king)
sismember IrvingCares king
sismember avCares king
計算3 我可能認識的人
SDIFF IrvingCares jamesCares-> {james.cjk}
五、ZSet
1、簡介
常用於排行榜,如視頻網站需要對用戶上傳視頻做排行榜,或點贊數與集合有聯繫,不能有重覆成員
2、常用命令
(1)添加命令
zadd key score member [score member......]
zadd user:zan 200 james //james的點贊數1, 返回操作成功的條數1
zadd user:zan 200 james 120 mike 100 lee// 返回3
zadd test:1 nx 100 james //鍵test:1必須不存在,主用於添加
zadd test:1 xx incr 200 james //鍵test:1必須存在,主用於修改,此時為300
zadd test:1 xx ch incr -299 james //返回操作結果1,300-299=1
(2)查詢命令
zrange test:1 0 -1 withscores //查看點贊(分數)與成員名
(3)計算成員個數
zcard test:1 //計算成員個數, 返回1
3、使用場景
排名場景:
zadd user:3 200 james 120 mike 100 lee//先插入數據
zrange user:3 0 -1 withscores //查看分數與成員
zrank user:3 james //返回名次:第3名返回2,從0開始到2,共3名
zrevrank user:3 james //返回0, 反排序,點贊數越高,排名越前
排行榜系統,如視頻網站需要對用戶上傳的視頻做排行榜
點贊數:
zadd user:1:20180106 3 mike //mike獲得3個贊
再獲一贊:
zincrby user:1:20180106 1 mike //在3的基礎上加1
用戶作弊,將用戶從排行榜刪掉:
zrem user:1:20180106 mike
展示贊數最多的5個用戶:
zrevrangebyrank user:1:20180106 0 4
查看用戶贊數與排名:
zscore user:1:20180106 mike zrank user:1:20180106 mike
實例
以最典型的微博熱搜為例,描述用Redis設計實現, 以日期做為Key
(1)點擊話題
zincrby topic:20230717 1 狗頭蘿莉
(2)上圖排行實現,展示今日前10排名
zrevrange topic:20230717 0 9 withscores
(3)統計近3日點擊數據
zunionstore topic:3day 3
(4) 展示近3日的排行前10名
zrevrange topic:20230717-20230717 0 9 withscores
4、ZSet和List、Set對比