redis 數據結構及常見命令

一、概述

Redis有5種數據結構,本文整理下數據結構都是什麼,包含了什麼常用命令,以及能用這些數據結構處理哪些類型的特性和數據。

目前爲止,我們所知道的Redis構成僅包括命令、關鍵字和值,還沒有接觸到關於數據結構的具體概念。當我們使用set命令時,Redis是怎麼知道我們是在使用哪個數據結構?其解決方法是,每個命令都相對應於一種特定的數據結構。例如,當你使用set命令,你就是將值存儲到一個字符串數據結構裏。而當你使用hset命令,你就是將值存儲到一個散列數據結構裏。考慮到Redis的關鍵字集很小,這樣的機制具有相當的可管理性。

二、字符串 String

在Redis裏,字符串是最基本最常用的數據結構。

  • 常用字符串命令如下

1. SET、GET

太簡單不說了

2. GETRANGE

獲取存儲在指定 key 中字符串的子字符串
在這裏插入圖片描述

3. GETSET

將給定 key 的值設爲 value ,並返回 key 的舊值

4. GETBIT、SETBIT

都是位操作
GETBIT key offset value 對 key 所儲存的字符串值,獲取指定偏移量上的位(bit),SETBIT就是清除或者設置了
這玩意有啥用呢,這可有大用了:
具體場景如下:
騰訊10億用戶,要幾個毫秒內查詢到某個用戶是否在線,你能怎麼做?千萬別說給每個用戶建立一個key,然後挨個記(你可以算一下需要的內存會很恐怖,而且這種類似的需求很多,騰訊光這個得多花多少錢。。)
原理是:
redis內構建一個足夠長的數組,每個數組元素只能是0和1兩個值,然後這個數組的下標index用來表示我們上面例子裏面的用戶id(必須是數字哈),那麼很顯然,這個幾億長的大數組就能通過下標和元素值(0和1)來構建一個記憶系統,就能實現上述場景。用到的命令是:setbit、getbit、bitcount

先來說說setbit、getbit、bitcount這三個指令的用法:
在學習這幾個命令之前,我們得先了解下redis中字符串的存儲方式,redis中的字符串都是以二進制的方式進行存儲的,比如說我執行如下命令:
在這裏插入圖片描述
我們知道 ‘a’ 的ASCII碼是 97。轉換爲二進制是:01100001。我們BIT相關命令都是對這個二進制數據進行操作

GETBIT
GETBIT命令可以返回key對應的value在offset(偏移)處的bit值,以上文提到的kk爲例,a對應的二進制數據是01100001,所以當offset爲0時,對應的bit值爲0;offset爲1時,對應的bit值爲1;offset爲2時,對應的bit值爲1;offset爲3時,對應的bit值爲0,依此類推….,如下:
在這裏插入圖片描述
通過上述結果,可以看到offset從0到7,就是01100001,也就是說offset是從左往右計數的,也就是從高位往低位。當超過位數時,結果是0

BITCOUNT
BITCOUNT可以用來統計這個二進制數據中1的個數,如下:
在這裏插入圖片描述
官網上有一個非常有意思的案例:用戶上線次數統計。節選部分原文如下:
在這裏插入圖片描述
SETBIT
我們通過SETBIT 命令將 andy中的 ‘a’ 變成 ‘b’ 應該怎麼變呢?
也就是將 01100001 變成 01100010 (b的ASCII碼是98),這個很簡單啦,也就是將’a’中的offset 6從0變成1,將offset 7 從1變成0。如下圖:
在這裏插入圖片描述
大家可能也發現了,每次SETBIT完畢之後,有一個(integer) 0或者(integer)1的返回值,這個是在你進行SETBIT 之前,該offset位的比特值。

另外使用 BITPOS 指令可以用來獲取二進制位串中第一個1或者0的位置,如下:
在這裏插入圖片描述

5. MGET、MSET

讀取、設置一個或多個key的值
在這裏插入圖片描述

6. SETEX、PSETEX

SETEX key seconds value
爲指定的 key 設置值及其過期時間。如果 key 已經存在, SETEX 命令將會替換舊的值。
PSETEX也一樣,但是以毫秒爲單位

7. SETNX、MSETNX

只有key不存在的時候纔會設置key的值,存在的話不覆蓋
同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在

8. SETRANGE

SETRANGE key offset value 用 value 參數覆寫給定 key 所儲存的字符串值,從偏移量 offset 開始

9. STRLEN

返回 key 所儲存的字符串值的長度

10. INCR、INCRBY、INCRBYFLOAT

把key中存儲的數字的值加一
INCRBY key increment將 key 所儲存的值加上給定的增量值(increment)
INCRBYFLOAT key increment將 key 所儲存的值加上給定的浮點增量值(increment)

11.DECR、DECRBY

上面是加,這裏就是減了

12. APPEND

APPEND key value
如果 key 已經存在並且是一個字符串, APPEND 命令將指定的 value 追加到該 key 原來值(value)的末尾,如果 key 不存在, APPEND 就簡單地將給定 key 設爲 value ,就像執行 SET key value 一樣

Redis的字符串數據結構比我當初所想的要有用許多。又能存儲對象又能計數。還能用來做緩存用。

三、哈希表 Hash

我們已經知道把Redis稱爲一種關鍵字-值型存儲是不太準確的,hash數據結構是一個很好的例證。你會看到,在很多方面裏,散列數據結構很像字符串數據結構。兩者顯著的區別在於,散列數據結構提供了一個額外的間接層:一個字段(Field)

  • 哈希結構常用的命令有

1.HSET、HGET

HSET KEY_NAME FIELD VALUE 爲哈希表中的字段賦值,如果字段有了就覆蓋
HGET就是讀取
在這裏插入圖片描述

2. HDEL

刪除哈希表 key 中的一個或多個指定字段,不存在的字段將被忽略
在這裏插入圖片描述

3. HEXISTS

查看哈希表 key 中,指定的字段是否存在

4. HGETALL

HGETALL key 獲取在哈希表中指定 key 的所有字段和值

5. HINCRBY、HINCRBYFLOAT

HINCRBY key field increment 爲哈希表 key 中的指定字段的整數值加上增量 increment
HINCRBYFLOAT key field increment 爲哈希表 key 中的指定字段的浮點數值加上增量 increment

6. HKEYS、HVALS

HKEYS key 獲取所有哈希表中的字段
HVALS key 獲取所有值

7. HLEN

HLEN key 獲取哈希表中字段的數量

8.HMGET、HMSET

獲取、設置多個字段的值
在這裏插入圖片描述

9. HSETNX

HSETNX key field value 只有在字段 field 不存在時,設置哈希表字段的值

10. HSCAN

當我們需要遍歷Redis所有key或者指定模式的key時,首先想到的是KEYS命令,但是如果redis數據非常大,並且key也非常多的情況下,查詢的時候很可能會很慢,造成整個redis阻塞,那麼有什麼辦法解決呢?就是scan和hscan

SCAN cursor [MATCH pattern] [COUNT count]
HSCAN key cursor [MATCH pattern] [COUNT count]

SCAN命令是一個基於遊標的迭代器, 這意味着命令每次被調用都需要使用上一次這個調用返回的遊標作爲該次調用的遊標參數,以此來延續之前的迭代過程, 當SCAN命令的遊標參數被設置爲 0 時, 服務器將開始一次新的迭代, 而當服務器向用戶返回值爲 0 的遊標時, 表示迭代已結束,HSCAN同SCAN命令相同。
在這裏插入圖片描述
more: http://www.redis.cn/commands/scan.html

哈希表數據結構比普通的字符串數據結構具有更多的可操作性。我們可以使用一個哈希表數據結構去獲得更精確的描述,是存儲一個用戶,而不是一個序列化對象。從而得到的好處是能夠提取、更新和刪除具體的數據片段,而不必去獲取或寫入整個值。

對於散列數據結構,可以從一個經過明確定義的對象的角度來考慮,例如一個用戶,關鍵之處在於要理解他們是如何工作的。從性能上的原因來看,這是正確的,更具粒度化的控制可能會相當有用。

四、列表 lists

對於一個給定的關鍵字,列表數據結構讓你可以存儲和處理一組值。你可以添加一個值到列表裏、獲取列表的第一個值或最後一個值以及用給定的索引來處理值。列表數據結構維護了值的順序,提供了基於索引的高效操作。

  • 列表常用命令

1. LPUSH、LPUSHX、RPUSH、RPUSHX

LPUSH 將一個或多個值插入到列表頭部,如果 key 不存在,一個空列表會被創建並執行 LPUSH 操作。 當 key 存在但不是列表類型時,返回一個錯誤。
LPUSHX 將一個值插入到已存在的列表頭部,列表不存在時操作無效。
RPUSH 將一個或多個值插入到列表尾部
RPUSHX 將一個值插入到已存在的列表尾部(最右邊)。如果列表不存在,操作無效。

2. LPOP 、RPOP

LPOP、RPOP key移出並獲取列表的第一個、最後一個元素

3. BLPOP、BRPOP

BLPOP key1 [key2 ] timeout 移出並獲取列表的第一個、最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。

4. RPOPLPUSH、BRPOPLPUSH

RPOPLPUSH SOURCE_KEY_NAME DESTINATION_KEY_NAME 移除列表的最後一個元素,並將該元素添加到另一個列表並返回
BRPOPLPUSH LIST1 ANOTHER_LIST TIMEOUT 從列表中取出最後一個元素,並插入到另外一個列表的頭部; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。

5. LINDEX

LINDEX key index 通過索引獲取列表中的元素

6. LINSERT

LINSERT key BEFORE|AFTER pivot value 在列表的pivot元素前或者後插入元素

7. LLEN

LLEN key 獲取列表長度

8. LRANGE

LRANGE key start stop 獲取列表指定範圍內的元素

9.LREM

LREM key count value
Redis Lrem 根據參數 COUNT 的值,移除列表中與參數 VALUE 相等的元素。
COUNT 的值可以是以下幾種:
count > 0 : 從表頭開始向表尾搜索,移除與 VALUE 相等的元素,數量爲 COUNT 。
count < 0 : 從表尾開始向表頭搜索,移除與 VALUE 相等的元素,數量爲 COUNT 的絕對值。
count = 0 : 移除表中所有與 VALUE 相等的值。

10. LSET

LSET key index value 通過索引設置列表元素的值

11. LTRIM

LTRIM key start stop 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除

對於存儲和索引關鍵字的功能,並不是只有列表數據結構這種方式。值可以是任意的東西,
我們可以使用列表數據結構去存儲日誌,也可以用來跟蹤用戶瀏覽網站時的路徑或者使用列表數據結構去跟蹤用戶的排隊活動。

五、集合 Sets

集合數據結構常常被用來存儲只能唯一存在的值,並提供了許多的基於集合的操作,例如並集。集合數據結構沒有對值進行排序,但是其提供了高效的基於值的操作。使用集合數據結構的典型用例是朋友名單的實現:
在這裏插入圖片描述
不管一個用戶有多少個朋友,我們都能高效地(O(1)時間複雜度)識別出用戶X是不是用戶Y的朋友:

sismember friends:leto jessica
sismember friends:leto vladimir

甚至可以在一個新的關鍵字裏存儲結果:

sinterstore friends:leto_duncan friends:leto friends:duncan
  • 有時候需要對值的屬性進行標記和跟蹤處理,但不能通過簡單的複製操作完成,集合數據結構是解決此類問題的最好方法之一。

當然,對於那些需要運用集合操作的地方(例如交集和並集),集合數據結構就是最好的選擇。

  • 集合常用命令

1. SADD

SADD key member1 [member2] 向集合添加一個或多個成員

2. SCARD

SCARD key 獲取集合的成員數

3. SDIFF

SDIFF key1 [key2] 返回給定所有集合的差集
在這裏插入圖片描述

4. SDIFFSTORE

SDIFFSTORE destination key1 [key2]
將給定集合之間的差集存儲在指定的集合中。如果指定的集合 key 已存在,則會被覆蓋。

5. SINTER

SINTER key1 [key2]
返回給定所有集合的交集

6. SINTERSTORE

SINTERSTORE destination key1 [key2] 返回給定所有集合的交集並存儲在 destination 中

7. SISMEMBER

SISMEMBER key member 判斷 member 元素是否是集合 key 的成員

8. SMEMBERS

SMEMBERS key 返回集合中的所有成員

9. SMOVE

SMOVE source destination member 將 member 元素從 source 集合移動到 destination 集合

10. SPOP

移除並返回集合中的一個隨機元素

11. SRANDMEMBER

SRANDMEMBER key [count] 返回集合中一個或多個隨機數

12. SREM

SREM key member1 [member2]
移除集合中一個或多個,不存在的成員元素會被忽略。

13. SUNION

返回所有給定集合的並集
在這裏插入圖片描述

14. SUNIONSTORE

SUNIONSTORE destination key1 [key2] 所有給定集合的並集存儲在 destination 集合中

15. SSCAN

SSCAN key cursor [MATCH pattern] [COUNT count]
迭代集合中的元素,迭代具體作用可以參考:http://www.redis.cn/commands/scan.html
在這裏插入圖片描述

六、 有序集合(Sorted Sets)

有序集合和集合一樣也是string類型元素的集合,且不允許重複的成員。
不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來爲集合中的成員進行從小到大的排序。
有序集合的成員是唯一的,但分數(score)卻可以重複。

  • 最常見的應用案例是用來實現排行榜系統。

對於一些基於整數排序,且能以標記來進行有效操作的東西,使用有序集合數據結構來處理應該都是不錯的選擇。

  • 有序集合常用命令

1. ZADD

向有序集合添加一個或多個成員,或者更新已存在成員的分數

2. ZCARD

獲取有序集合的成員數

3. ZCOUNT

ZCOUNT key min max 計算在有序集合中指定區間分數的成員數
在這裏插入圖片描述

4. ZINCRBY

ZINCRBY key increment member 有序集合中對指定成員的分數加上增量 increment

5. ZINTERSTORE

ZINTERSTORE destination numkeys key [key …] 計算給定的一個或多個有序集的交集並將結果集存儲在新的有序集合 key 中,numkeys代表後面有幾個key
在這裏插入圖片描述

6. ZLEXCOUNT

ZLEXCOUNT key min max在有序集合中計算指定字典區間內成員數量
在這裏插入圖片描述

7. ZRANGE

ZRANGE key start stop [WITHSCORES] 返回有序集中,指定區間內的成員。

其中成員的位置按分數值遞增(從小到大)來排序。
具有相同分數值的成員按字典序(lexicographical order )來排列。
下標參數 start 和 stop 都以 0 爲底,也就是說,以 0 表示有序集第一個成員,以 1 表示有序集第二個成員,以此類推。
你也可以使用負數下標,以 -1 表示最後一個成員, -2 表示倒數第二個成員,以此類推。帶WITHSCORES參數就顯示分數值,不帶就只顯示元素值
在這裏插入圖片描述

8. ZRANGEBYLEX

ZRANGEBYLEX key min max [LIMIT offset count] 通過字典區間返回有序集合的成員
在這裏插入圖片描述

9. ZRANGEBYSCORE

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 通過分數返回有序集合指定區間內的成員

10. ZRANK

ZRANK key member 返回有序集中指定成員的排名。其中有序集成員按分數值遞增(從小到大)順序排列。

11. ZREM

ZREM key member [member …] 移除有序集合中的一個或多個成員

12. ZREMRANGEBYLEX

ZREMRANGEBYLEX key min max 移除有序集合中給定的字典區間的所有成員

13. ZREMRANGEBYRANK

ZREMRANGEBYRANK key start stop 移除有序集合中給定的排名區間的所有成員

14. ZREMRANGEBYSCORE

ZREMRANGEBYSCORE key min max 移除有序集合中給定的分數區間的所有成員

15. ZREVRANGE

ZREVRANGE key start stop [WITHSCORES] 返回有序集中指定區間內的成員,通過索引,分數從高到底

16. ZREVRANGEBYSCORE

ZREVRANGEBYSCORE key max min [WITHSCORES] 返回有序集中指定分數區間內的成員,分數從高到低排序

17. ZREVRANK

ZREVRANK key member 返回有序集合中指定成員的排名,有序集成員按分數值遞減(從大到小)排序

18. ZSCORE

ZSCORE key member 返回有序集中,成員的分數值

19. ZUNIONSTORE

ZUNIONSTORE destination numkeys key [key …] 計算給定的一個或多個有序集的並集,並存儲在新的 key 中

20. ZSCAN

ZSCAN key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成員和元素分值)
迭代具體作用可以參考:http://www.redis.cn/commands/scan.html

七、小結

對於Redis的5種數據結構,我們進行了高層次的概述。一件有趣的事情是,相對於最初構建時的想法,你經常能用Redis創造出一些更具實效的事情。對於字符串數據結構和分類集合數據結構的使用,很有可能存在一些構建方法是還沒有人想到的。當你理解了那些常用的應用案例後,你將發現Redis對於許多類型的問題,都是很理想的選擇。還有,不要因爲Redis展示了5種數據結構和相應的各種方法,就認爲你必須要把所有的東西都用上。只使用一些命令去構建一個特性是很常見的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章