本博客屬作者原創,未經允許禁止轉載,請尊重原創!如有問題請聯繫QQ509961766
Redis 不像傳統數據庫一樣,有table的概念,schema 所對應的db僅以編號區分。同一個db 內,key 作爲頂層模型,它的值是扁平化的。也就是說db 就是key的命名空間。
我們都知道,在 redis 中一共有5種數據結構,那每種數據結構的使用場景都是什麼呢?
- String-字符串
- Hash-字典
- List-列表
- Set-集合
- Sorted Set-有序集合
下面我們就來簡單彙總一下,這個5種類型的常用命令,以及使用場景,在什麼情況下使用哪種數據結構。這裏只列出的常用命令,後面有章節會詳細的介紹各自的命令,對命令不熟悉的同學可以打開客戶端跟着練習,這樣有助於理解數據類型,也熟悉的常用命令。話不多說,進入正題。
1.String字符串
String 數據結構是最常用的類型,可以說很多人除了String,別的數據類型基本沒用過, 跟其他語言中的字符串一樣,形如key value,如hello world, hello是key, world是值。value 不僅可以是 String,也可以是數字。總之,string可以存一切內容,什麼都能存,只不過要看具體的使用場景。
命令 | 描述 |
---|---|
SET key value | 設置指定 key 的值 |
GET key | 獲取指定 key 的值 |
SETNX key value | 只有在 key 不存在時設置 key 的值 |
SETEX key seconds value | 設置key的值 ,並將 key 的過期時間設爲 seconds (以秒爲單位) |
APPEND key value | 將字符串添加到末尾 |
打開客戶端練習一下
舉個例子,存key=hello,value=this is a redis test
String的應用場景
1.儲存某個字符串,字段
2.儲存某個對象
3.計數器,字符串是整數時,可以使用自增,自減,例如id自增,微信點贊自增
4.Redis的所有操作都是單線程保證了數據的原子性,在高併發場景下保證數據的一致性
2.Hash字典
我們經常將一些結構化的信息打包成 hashmap,在客戶端序列化後存儲爲一個字符串的值(一般是 JSON 格式),比如用戶的暱稱、年齡、性別、積分等。這時候在需要修改其中某一項時,通常需要將字符串(JSON)取出來,然後進行反序列化,修改某一項的值,再序列化成字符串(JSON)存儲回去。簡單修改一個屬性就幹這麼多事情,消耗必定是很大的,也不適用於一些可能併發操作的場合(比如兩個併發的操作都需要修改積分)。而 Redis 的 Hash 結構可以使你像在數據庫中 Update 一個屬性一樣只修改某一項屬性值。Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。
命令 | 描述 |
---|---|
HSET key field value | 將哈希表 key 中的字段 field 的值設爲 value |
HMSET key field1 value1 [field2 value2 ] | 同時將多個 field-value (域-值)對設置到哈希表 key 中 |
HMGET key field1 [field2] | 獲取所有給定字段的值 |
HKEYS key | 獲取所有哈希表中的字段 |
打開客戶端練習一下
舉個例子,例如我要存科比這個人的姓名,年齡,性別,生日,湖人隊等信息
命令就是:HMSET kobe name “bryant” age 42 sex “man” birth “2020-08-23” team “Lakers”
Hash的應用場景
hash 類型十分適合存儲對象類數據。
相比於在 String 中介紹的把對象轉化爲 json 字符串存儲,
Hash 的結構可以任意添加或刪除‘字段名’,更加高效靈活。
而String中存json對象,如果要修改json中某個屬性,開銷是很大的。
而Hash類型可以很好的解決這個問題,大大減小開銷
3.List列表(有序可重複)
List 是按照插入順序排序的字符串鏈表,可以在頭部和尾部插入新的元素(redis 使用雙端鏈表實現的 List)。使用 List 結構,我們可以輕鬆地實現最新消息排行等功能(比如新浪微博的 TimeLine )。List 的另一個應用就是消息隊列,可以利用 List 的 *PUSH 操作,將任務存在 List 中,然後工作線程再用 POP 操作將任務取出進行執行。
命令 | 描述 |
---|---|
LPUSH key value1 [value2] | 將一個或多個值插入到列表頭部 |
LPUSHX key value | 將一個值插入到已存在的列表頭部 |
LRANGE key start stop | 獲取列表指定範圍內的元素 |
LLEN key | 獲取列表長度 |
打開客戶端練習一下
舉個例子,存科比相關的所有屬性到list中
命令是LPUSH player kobe bryant 42 man 1978-08-23 Lakers PG
然後LLEN player可以查看list的長度
然後LRANGE player 0 6 可以根據下標來獲取list,注意一定要帶下標,否則命令錯誤。
下標不對不會出錯,只不過會獲取到空集合,例如start大於end下標
List的應用場景
1.消息隊列,list類型的lpop和rpush能實現隊列的功能
2.最新消息,list類型的lpush命令和lrange命令能實現最新列表的功能,
每次通過lpush命令往列表裏插入新的元素,然後通過lrange命令讀取最新的元素列表,
如朋友圈的點贊列表、評論列表。
3.排行榜,list類型的lrange命令可以分頁查看隊列中的數據。可將每隔一段時間計算一次的排行榜存儲在list類型中
4.由於list 是鏈表結構,所有如果在頭部和尾部插入數據,性能會非常高,不受鏈表長度的影響;
但如果在鏈表中插入數據,性能就會越來越差。
4.Set集合(無序不可重複)
Set 就是一個集合,集合的概念就是一堆不重複值的組合。利用 Redis 提供的 Set 數據結構,可以存儲一些集合性的數據。而且set集合當中元素是沒有順序的,不存在元素下標。比如在微博應用中,可以將一個用戶所有的關注人存在一個集合中,將其所有粉絲存在一個集合。因爲 Redis 非常人性化的爲集合提供了求交集、並集、差集等操作,那麼就可以非常方便的實現如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是存集到一個新的集合中。
命令 | 描述 |
---|---|
SADD key member1 [member2] | 向集合添加一個或多個成員 |
SCARD key | 獲取集合的長度 |
SISMEMBER key member | 判斷 member 元素是否是集合 key 的成員 |
SMEMBERS key | 返回集合中的所有成員 |
SREM key member1 [member2] | 移除集合中一個或多個成員 |
打開客戶端練習一下
舉個例子,存NBA中球員的名字到set集合中
SADD NBA kobe harden curry james westbrook lillard durant paul irving love anthony embiid
然後查看集合SMEMBERS NBA
然後查看集合長度SCARD NBA
然後判斷Jordan是否在集合中
然後刪除元素kobe
Set的應用場景
1.共同好友/關注/粉絲/感興趣/黑名單的人集合,求交集,並集,差集
2.隨機集合,由於set是無序集合,適合一些隨機使用場景,例如微博推薦,標籤等等
5.Sorted Set有序集合
和Set相比,Sorted Sets是將 Set 中的元素增加了一個權重參數 score,使得集合中的元素能夠按 score 進行有序排列,比如一個存儲NBA球員技術統計集合,其集合 value 可以是球員的號碼,而 score 就可以是球員的得分,這樣在數據插入集合的時候,就已經進行了天然的排序。另外還可以用 Sorted Sets 來做帶權重的隊列,比如普通消息的 score 爲1,重要消息的 score 爲2,然後工作線程可以選擇按 score 的倒序來獲取工作任務。讓重要的任務優先執行。
命令 | 描述 |
---|---|
ZADD key score1 member1 [score2 member2] ] | 向有序集合添加一個或多個成員,或者更新已存在成員的分數 |
ZCARD key | 獲取集合的長度 |
ZSCORE key member | 返回有序集中,成員的分數值 |
ZRANGE key start stop [WITHSCORES] | 通過索引區間返回有序集合指定區間內的成員 |
打開客戶端練習一下
例如存NBA本賽季球員得分榜
ZADD SCORE 33.4 HARDEN 29.1 JAMES 28.8 DURANT 27.7 CURRY 27.1 WESTBROOK 27.1 LILLARD
然後ZCARD SCORE查看長度
然後ZSCORE SCORE JAMES 查看詹姆斯的分數
然後ZRANGE SCORE 0 5查看前6名得分榜
Sorted Set的應用場景
1.好友親密度
2.NBA球員得分榜