手機應用軟件開發(fā)seo在線教程
Redis 共有 5 種基本數(shù)據(jù)類型:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。
這 5 種數(shù)據(jù)類型是直接提供給用戶使用的,是數(shù)據(jù)的保存形式,其底層實現(xiàn)主要依賴這 8 種數(shù)據(jù)結(jié)構(gòu):簡單動態(tài)字符串(SDS)、LinkedList(雙向鏈表)、Dict(哈希表/字典)、SkipList(跳躍表)、Intset(整數(shù)集合)、ZipList(壓縮列表)、QuickList(快速列表)。
Redis 5 種基本數(shù)據(jù)類型對應的底層數(shù)據(jù)結(jié)構(gòu)實現(xiàn)如下表所示:
String | List | Hash | Set | Zset |
---|---|---|---|---|
SDS | LinkedList/ZipList/QuickList | Dict、ZipList | Dict、Intset | ZipList、SkipList |
StringListHashSetZsetSDSLinkedList/ZipList/QuickListDict、ZipListDict、IntsetZipList、SkipListRedis 3.2 之前,List 底層實現(xiàn)是 LinkedList 或者 ZipList。
Redis 3.2 之后,引入了 LinkedList 和 ZipList 的結(jié)合 QuickList,List 的底層實現(xiàn)變?yōu)?QuickList。從 Redis 7.0 開始, ZipList 被 ListPack 取代。
String(字符串)
介紹
String 是 Redis 中最簡單同時也是最常用的一個數(shù)據(jù)類型。String 是一種二進制安全的數(shù)據(jù)類型,可以用來存儲任何類型的數(shù)據(jù)比如字符串、整數(shù)、浮點數(shù)、圖片(圖片的 base64 編碼或者解碼或者圖片的路徑)、序列化后的對象。
雖然 Redis 是用 C 語言寫的,但是 Redis 并沒有使用 C 的字符串表示,而是自己構(gòu)建了一種 簡單動態(tài)字符串(Simple Dynamic String,SDS)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本數(shù)據(jù)還可以保存二進制數(shù)據(jù),并且獲取字符串長度復雜度為 O(1)(C 字符串為 O(N)),除此之外,Redis 的 SDS API 是安全的,不會造成緩沖區(qū)溢出.
應用場景
- 需要存儲常規(guī)數(shù)據(jù)的場景舉例:
緩存 Session、Token、圖片地址、序列化后的對象(相比較于 Hash 存儲更節(jié)省內(nèi)存)。相關(guān)命令:SET、GET。 - 需要計數(shù)的場景舉例:用戶單位時間的請求數(shù)(簡單限流可以用到)、頁面單位時間的訪問數(shù)。相關(guān)命令:SET、GET、 INCR、DECR 。
- 分布式鎖
利用 SETNX key value 命令可以實現(xiàn)一個最簡易的分布式鎖(存在一些缺陷,通常不建議這樣實現(xiàn)分布式鎖)。
List(列表)
介紹
Redis 中的 List 其實就是鏈表數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)。許多高級編程語言都內(nèi)置了鏈表的實現(xiàn)比如 Java 中的 LinkedList,但是 C 語言并沒有實現(xiàn)鏈表,所以 Redis 實現(xiàn)了自己的鏈表數(shù)據(jù)結(jié)構(gòu)。Redis 的 List 的實現(xiàn)為一個 雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷。
常用命令
命令 | 介紹 |
---|---|
RPUSH key value1 value2 … | 在指定列表的尾部(右邊)添加一個或多個元素 |
RPUSH key value1 value2 … | 在指定列表的尾部(右邊)添加一個或多個元素 |
LPUSH key value1 value2 … | 在指定列表的頭部(左邊)添加一個或多個元素 |
LSET key index value | 將指定列表索引 index 位置的值設(shè)置為 value |
LPOP key | 移除并獲取指定列表的第一個元素(最左邊) |
RPOP key | 移除并獲取指定列表的最后一個元素(最右邊) |
LLEN key | 獲取列表元素數(shù)量 |
LRANGE key start end | 獲取列表 start 和 end 之間 的元素 |
我專門畫了一個圖方便大家理解 RPUSH , LPOP , lpush , RPOP 命令:
應用場景
- 信息流展示
- 舉例:最新文章、最新動態(tài)。
- 相關(guān)命令:LPUSH、LRANGE。
- 消息隊列
List 可以用來做消息隊列,只是功能過于簡單且存在很多缺陷,不建議這樣做。
相對來說,Redis 5.0 新增加的一個數(shù)據(jù)結(jié)構(gòu) Stream 更適合做消息隊列一些,只是功能依然非常簡陋。和專業(yè)的消息隊列相比,還是有很多欠缺的地方比如消息丟失和堆積問題不好解決。
Hash(哈希)
介紹
Redis 中的 Hash 是一個 String 類型的 field-value(鍵值對) 的映射表,特別適合用于存儲對象,后續(xù)操作的時候,你可以直接修改這個對象中的某些字段的值。
Hash 類似于 JDK1.8 前的 HashMap,內(nèi)部實現(xiàn)也差不多(數(shù)組 + 鏈表)。不過,Redis 的 Hash 做了更多優(yōu)化。
常用命令
命令 | 介紹 |
---|---|
HSET key field value | 設(shè)置指定哈希表中指定字段的值 |
HSETNX key field value | 只有指定字段不存在時設(shè)置指定字段的值 |
HMSET key field1 value1 field2 value2 … | 同時將一個或多個 field-value (域-值)對設(shè)置到指定哈希表中 |
HGET key field | 獲取指定哈希表中指定字段的值 |
HMGET key field1 field2 … | 獲取指定哈希表中一個或者多個指定字段的值 |
HGETALL key | 獲取指定哈希表中所有的鍵值對 |
HEXISTS key field | 查看指定哈希表中指定的字段是否存在 |
HDEL key field1 field2 … | 刪除一個或多個哈希表字段 |
HLEN key | 獲取指定哈希表中字段的數(shù)量 |
HINCRBY key field increment | 對指定哈希中的指定字段做運算操作(正數(shù)為加,負數(shù)為減) |
應用場景
對象數(shù)據(jù)存儲場景舉例:用戶信息、商品信息、文章信息、購物車信息。
相關(guān)命令:HSET (設(shè)置單個字段的值)、HMSET(設(shè)置多個字段的值)、HGET(獲取單個字段的值)、HMGET(獲取多個字段的值)。
Set(集合)
介紹
Redis 中的 Set 類型是一種無序集合,集合中的元素沒有先后順序但都唯一,有點類似于 Java 中的 HashSet 。當你需要存儲一個列表數(shù)據(jù),又不希望出現(xiàn)重復數(shù)據(jù)時,Set 是一個很好的選擇,并且 Set 提供了判斷某個元素是否在一個 Set 集合內(nèi)的重要接口,這個也是 List 所不能提供的。你可以基于 Set 輕易實現(xiàn)交集、并集、差集的操作,比如你可以將一個用戶所有的關(guān)注人存在一個集合中,將其所有粉絲存在一個集合。這樣的話,Set 可以非常方便的實現(xiàn)如共同關(guān)注、共同粉絲、共同喜好等功能。這個過程也就是求交集的過程。
常用命令
命令 | 介紹 |
---|---|
SADD key member1 member2 … | 向指定集合添加一個或多個元素 |
SMEMBERS key | 獲取指定集合中的所有元素 |
SCARD key | 獲取指定集合的元素數(shù)量 |
SISMEMBER key | member判斷指定元素是否在指定集合中 |
SINTER key1 key2 … | 獲取給定所有集合的交集 |
SINTERSTORE destination key1 key2 … | 將給定所有集合的交集存儲在 destination 中 |
SUNION key1 key2 … | 獲取給定所有集合的并集 |
SUNIONSTORE destination key1 key2 … | 將給定所有集合的并集存儲在 destination 中 |
SDIFF key1 key2 … | 獲取給定所有集合的差集 |
SDIFFSTORE destination key1 key2 … | 將給定所有集合的差集存儲在 destination 中 |
SPOP key count | 隨機移除并獲取指定集合中一個或多個元素 |
SRANDMEMBER key count | 隨機獲取指定集合中指定數(shù)量的元素 |
應用場景
需要存放的數(shù)據(jù)不能重復的場景
- 舉例:網(wǎng)站 UV 統(tǒng)計(數(shù)據(jù)量巨大的場景還是 HyperLogLog更適合一些)、文章點贊、動態(tài)點贊等場景。
- 相關(guān)命令:SCARD(獲取集合數(shù)量)
需要獲取多個數(shù)據(jù)源交集、并集和差集的場景
- 舉例:共同好友(交集)、共同粉絲(交集)、共同關(guān)注(交集)、好友推薦(差集)、音樂推薦(差集)、訂閱號推薦(差集+交集) 等場景。
- 相關(guān)命令:SINTER(交集)、SINTERSTORE (交集)、SUNION (并集)、SUNIONSTORE(并集)、SDIFF(差集)、SDIFFSTORE (差集)。
需要隨機獲取數(shù)據(jù)源中的元素的場景
- 舉例:抽獎系統(tǒng)、隨機點名等場景。
- 相關(guān)命令:SPOP(隨機獲取集合中的元素并移除,適合不允許重復中獎的場景)、SRANDMEMBER(隨機獲取集合中的元素,適合允許重復中獎的場景)。
Sorted Set(有序集合)
介紹
Sorted Set 類似于 Set,但和 Set 相比,Sorted Set 增加了一個權(quán)重參數(shù) score,使得集合中的元素能夠按 score 進行有序排列,還可以通過 score 的范圍來獲取元素的列表。有點像是 Java 中 HashMap 和 TreeSet 的結(jié)合體。
常用命令
命令 | 介紹 |
---|---|
ZADD key score1 member1 score2 member2 … | 向指定有序集合添加一個或多個元素 |
ZCARD KEY | 獲取指定有序集合的元素數(shù)量 |
ZSCORE key member | 獲取指定有序集合中指定元素的 score 值 |
ZINTERSTORE destination numkeys key1 key2 … | 將給定所有有序集合的交集存儲在 destination 中,對相同元素對應的 score 值進行 SUM 聚合操作,numkeys 為集合數(shù)量 |
ZUNIONSTORE destination numkeys key1 key2 … | 求并集,其它和 ZINTERSTORE 類似 |
ZDIFFSTORE destination numkeys key1 key2 … | 求差集,其它和 ZINTERSTORE 類似 |
ZRANGE key start end | 獲取指定有序集合 start 和 end 之間的元素(score 從低到高) |
ZREVRANGE key start end | 獲取指定有序集合 start 和 end 之間的元素(score 從高到底) |
ZREVRANK key member | 獲取指定有序集合中指定元素的排名(score 從大到小排序) |
應用場景
需要隨機獲取數(shù)據(jù)源中的元素根據(jù)某個權(quán)重進行排序的場景
- 舉例:各種排行榜比如直播間送禮物的排行榜、朋友圈的微信步數(shù)排行榜、王者榮耀中的段位排行榜、話題熱度排行榜等等。
- 相關(guān)命令:ZRANGE (從小到大排序)、 ZREVRANGE (從大到小排序)、ZREVRANK (指定元素排名)。
需要存儲的數(shù)據(jù)有優(yōu)先級或者重要程度的場景 比如優(yōu)先級任務(wù)隊列。
- 舉例:優(yōu)先級任務(wù)隊列。
- 相關(guān)命令:ZRANGE (從小到大排序)、 ZREVRANGE (從大到小排序)、ZREVRANK (指定元素排名)。
總結(jié)
數(shù)據(jù)類型 | 說明 |
---|---|
String | 一種二進制安全的數(shù)據(jù)類型,可以用來存儲任何類型的數(shù)據(jù)比如字符串、整數(shù)、浮點數(shù)、圖片(圖片的 base64 編碼或者解碼或者圖片的路徑)、序列化后的對象。 |
List | Redis 的 List 的實現(xiàn)為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷。 |
Hash | 一個 String 類型的 field-value(鍵值對) 的映射表,特別適合用于存儲對象,后續(xù)操作的時候,你可以直接修改這個對象中的某些字段的值。 |
Set | 無序集合,集合中的元素沒有先后順序但都唯一,有點類似于 Java 中的 HashSet 。 |
Zset | 和 Set 相比,Sorted Set 增加了一個權(quán)重參數(shù) score,使得集合中的元素能夠按 score 進行有序排列,還可以通過 score 的范圍來獲取元素的列表。有點像是 Java 中 HashMap 和 TreeSet 的結(jié)合體。 |