Redis 學習(二) —— 數據類型及操作


Redis支持string、list、set、zset、hash等數據類型,這一篇學習redis的數據類型、命令及某些使用場景。

 

一、String,字符串

字符串是 Redis 最基本的數據類型。一個字符串最大為 512M 字節。字符串數據類型適用於很多場景,例如,緩存 HTML 片段或者頁面。

Redis 字符串是二進制安全的,也就是說,一個 Redis 字符串可以包含任意類型的數據,例如一張 JPEG 圖像,或者一個序列化的對象。

我們可以把字符串當做位數組(位圖)來處理,很容易統計一些基於0/1邏輯的業務;

使用 INCR 命令族 (INCR,DECR,INCRBY),將字符串作為原子計數器;

使用 APPEND 命令追加字符串等等。

1、set key value [ex 秒數]/[px 毫秒數] [nx]/[xx]

set name tom,永久有效。

set name tom ex 60,60秒后過期。

set name tom px 6000,6000毫秒(6秒)后過期。

ex、px 不能同時寫,否則以后面一個時間為准。

如set name tom ex 60 px 6000,實際上6秒后就過期了。

nx表示key不存在時執行操作,xx表示key存在時執行操作。

2、setnx key value:key不存在時設置value

3、get key:獲取key的值

4、mset k1 v1 k2 v2 ... kn vn:multi set 一次性設置多個鍵值

5、msetnx k1 v1 k2 v2 ... kn vn:設置多個鍵值,當鍵不存在時才設置

只要有一個存在就都不會被設置。

6、mget k1 k2 .. kn:獲取多個key的值

7、setrange key offset value:將key對應的值,偏移offset位置的字符替換為value。

返回新字符串的長度。

偏移量的下標以0開始,value有多少個長度,則替換多少個長度的字符。

如果offset超出字符串的長度,則以空白的部分以0x00填充。

8、getrange key start end:獲取字符串中[start, end]范圍的值

字符串下標左數從0開始,右數從-1開始。

獲取左邊第二個(1)到右邊第一個(-2)的值。

start >= length,返回空字符串。end >= length,截取至字符結尾。

9、getset key newvalue:獲取原值,並設置新值

10、append key value:把value追加到key的原值上

11、strlen key:獲取key值的長度

12、incr/decr key:指定key的值加1或減1,返回加1或減1后的值

incr/decr 命令將字符串值解析為整數,可作為原子計數器。incr 命令是原子的,因為即使多個客戶端對同一個鍵發送 incr 命令也不會造成競爭條件,讀 - 加/減 - 寫操作在執行時,其他客戶端此時不會執行相關命令。

incr/decr通常可用於計數、搶單的場合,例如有2000張火車票,同時有10萬人搶2000張火車票,可能一分鍾內就搶完了。如果同時去數據庫查詢剩余票數或下訂單,數據庫壓力很大。

此時可在redis中設置一個票數的緩存,搶票的人先搶到下訂單的資格,后台再慢慢去下訂單更新數據庫。獲得資格后,自動減一,並返回了剩余票數。剩余票數為0,就可過濾掉絕大部分請求了。

如果key不存在,則默認key為0,再執行加減的操作。

13、incrby/decrby key num:指定的key值加或減num,返回加num或減num后的值

num為整數。

14、incrbyfloat key float:key值加float,float為浮點數

如果要減少,float為負數即可。

15、setbit key offset value:設置key值的二進制位上offset對應的值

例如,我要將大寫的字母變為小寫的字母,大寫字母和小寫字母相差32,差異就是大寫字母二進制位偏移量2的位置為0,小寫字母為1,。

 

經典的應用就是使用位圖法統計活躍用戶,例如統計連續一周登錄用戶。

如果有1億用戶,登錄日志存儲在數據庫表中,表急劇增大,直接在數據庫中統計,計算較慢。

那么使用位圖法就能輕松解決這個問題,每天按日期生成一個位圖(位數組),用戶是否登錄就用1/0標識,用戶登錄后,把user_id位上的值置為1,標識該用戶已登錄。把一周的位圖做and運算,位上為1的就是連續登錄的用戶。

一個位圖算1億個位,100000000/8/1024/1024 ≈ 12M,也就是說每天只需要12M就能存儲1億用戶是否登錄的情況,節約空間,計算方便。

ID為100000000的用戶,設置周一、周二、周三連續登錄,最后做AND操作,得出該用戶連續登錄:

ID為5000的用戶,周一登錄,周二不登錄,周三登錄(可以不設置,默認填充0),做AND操作,得出未連續登錄:

16、getbit key offset:獲取key值的二進制位上offset對應的值

17、bitop operation destkey key1 key2 ... keyn:對key1、key2 ... keyn做operation操作,並將結果保存到destkey上

operation 可以是AND、OR、NOT、XOR

18、bitcount key:返回被置為1的位的數量

19、bitops key 1/0:返回第一個被置為1/0的位

 

二、List,鏈表

Redis列表是簡單的字符串列表,排序為插入的順序。列表的最大長度為2^32 - 1 。

Redis 的列表是使用鏈表實現的。這意味着,即使你的列表中有上百萬個元素,增加一個元素到列表的頭部或者尾部的操作都是在常量時間完成。Redis 采用鏈表來實現列表是因為,對於數據庫系統來說,快速插入一個元素到一個很長的列表非常重要。

我們可以用列表獲取最新的內容(像帖子、微博等),用ltrim很容易就獲取最新的內容,並移除舊的內容。

用列表可以實現生產者消費者模式,生產者調用 lpush 添加項到列表中,消費者調用 rpop 從列表提取,如果沒有元素,則輪詢去獲取,或者使用brpop等待生產者添加項到列表中。

1、lpush key value:把值插入鏈表頭部

插入成功,返回列表的個數。可以同時插入多個值。

lpushx key value:當key存在是才插入數據

2、lrange key start end:返回鏈表中[start, end]中的元素

左數從0開始,右數從-1開始。所以想取出全部元素可以用lrange key 0 -1。

3、rpush key value:把值插入鏈表的尾部

rpushx key value:當key存在是才插入數據。

4、lpop key:返回並刪除鏈表頭元素

5、rpop key:返回並刪除鏈表尾部元素

6、lrem key count value:從鏈表中刪除value值

刪除count絕對值個value,count>0,從頭部開始刪除;count<0,從尾部開始刪除。

7、ltrim key start end:截取[start, end]的列表並重新賦給key

有些時候我們只想用列表存儲最近的項,我們可以使用ltrim命令僅僅只記住最近的10項,而丟棄所有老的項。可以很容易實現新增一個元素而拋棄超出的元素。

8、lindex key index:返回列表索引index上的值

9、llen key:返回列表的個數

10、linsert key after|before search value:在列表中查找search,在search之后|之前插入value

只會在第一個匹配的search之后|之前插入,不會插入多個value。

 11、lset key index value:設置列表index位置的元素為value

12、brpop/blpop key timeout:等待彈出key的尾部/頭部元素

如果有元素則直接彈出,沒有則阻塞,timeout為等待超時時間,如果timeout為0,則一直等待。

一般可用於輪詢,在線聊天,例如有一個message列表,在獲取消息的時候,沒有就等待,有就彈出。

使用一個終端來等待消息:

另一個終端插入消息:

消息被彈出:

等待超時:

13、rpoplpush source dest:把source的尾部拿出來放到dest的頭部

使用rpoplpush相比分開rpop,lpush兩步操作是原子性的,使用 rpoplpush 可以構建更安全的隊列和旋轉隊列。

rpoplpush一般可用於構建安全任務隊列,比如有一個任務隊列task,每次從中取出一個任務來執行,放到另一個列表bak來備份。這樣任務如果執行成功,從bak列表中移除該任務;失敗,可以再拿回task列表。

14、brpoplpush source dest timout:等待彈出,放到dest中

結合了brpop喝rpoplpush的特性,有則彈出放到另一個列表,沒有則等待。

 

三、Set,集合

Redis 集合是無序的字符串集合,集合中的值是唯一的、無序的。可以對集合執行很多操作,例如,測試元素是否存在,對多個集合執行交集、並集和差集,等等。

我們通常可以用集合存儲一些無關順序的,表達對象間關系的數據,例如用戶的角色,可以用sismember很容易就判斷用戶是否擁有某個角色。

在一些用到隨機值的場合是非常適合的,可以用 srandmember/spop 獲取/彈出一個隨機元素。

1、sadd key val1 val2 ... valn:向集合中添加元素

2、srandmember key:隨機或一個元素

在string和list的命令中,可以通過range來獲取某幾個字符或某幾個元素,但集合是無序的,無法通過下標或范圍來訪問部分元素,因此要么隨機選一個,要么全選。

3、smembers key:返回列表的所有元素

4、sismember key value:判斷是否存在某個元素

存在則返回1,不存在則返回0

5、scard key:返回集合的個數

6、spop key:返回並刪除其中一個隨機元素

7、srem val1 val2 ... valn:刪除元素

8、smove source dest value:將source集合中的value刪除並移到dest中

9、sinter k1 k2 ... kn:求集合的交集

sinterstore dest k1 k2 ... kn:求集合的交集,並將結果賦給dest

11、sunion k1 k2 ... kn:求集合的並集

 同理,sunionstore則將並集的結果賦給dest。

可以用sunionstore復制一個集合

12、sdiff k1 k2 ... kn:求集合的差集

即k1-k2-kn

 

四、Sorted Set,有序集合

有序集合由唯一的,不重復的字符串元素組成。有序集合中的每個元素都關聯了一個浮點值,稱為分數。可以把有序看成hash和集合的混合體,分數即為hash的key。

有序集合中的元素是按序存儲的,不是請求時才排序的。

1、zadd key score1 value1 score2 value2 ... scoren valuen:添加元素

score為分數,他們按照如下規則排序:

  • 如果 A 和 B 是擁有不同分數的元素,A.score > B.score,則 A > B。
  • 如果 A 和 B 是有相同的分數的元素,如果按字典順序 A 大於 B,則 A > B。A 和 B 不能相同,因為排序集合只能有唯一元素。

向有序集合中添加元素,會自動排序且為升序

 有序集合的分數可以重復,但值不能重復,元素是唯一的。

2、zrange key start end [withscores]:獲取[start, end]的元素(升序)

withscores,是否顯示排序分數。zrange默認返回升序序列。

3、zrevrange key start end [withscores]:獲取[start, end]的元素(降序)

與zrange獲取的順序相反。

4、zrank key member:查member的排名(升序)

 返回的排名升序從下標0開始

5、zrevrank key member:查member的排名(降序)

返回的排名降序從下標0開始

6、zcard key:返回元素個數

7、zcount key min max:返回分數[min, max]區間的元素個數

 +inf表示正無窮,-inf表示負無窮。

8、zscore key member:獲取元素的分數

9、zrangebyscore key min max [withscores] [limit offset N]:獲取[min, max]區間並偏移offset個,取出后N個元素(升序)

類似於分頁查詢,如果N超出個數,返回直到結尾。

10、zrevrangebyscore key max min [withscores] [limit offset N]:獲取[max, min]區間並偏移offset個,取出后N個元素(降序)

與zrangebyscore順序相反,注意范圍是[max, min]

11、zrem key value1 value2 ... valuen:刪除元素

從這里也可以看出有序集合中的元素是唯一性的。

12、zremrangebyscore key min max:刪除分數[min, max]范圍的元素

13、zremrangebyrank key start end:刪除排名[min, max]之間的元素

14、zinterstore dest numkeys key1 [key2 ... keyn] [weights weight1 [weight2 ... weightn]] [aggregate sum|min|max]

求key1、key2的交集,key1、key2的權重分別是weight1、weight2;numkeys指定key的個數。

聚合方法為sum|min|max,結果保存到dest中,默認交集求和。可以看做先做交集再做后面的運算。

同樣,取並集用zunionstore,其余參數一樣。

添加兩組數據:

交集求和:

交集最大值:

交集加上權重取最大值:加上權重時:score = score * weight

 

五、Hash,哈希

Redis的哈希值是字符串字段和字符串值之間的映射,是表示對象的完美數據類型。

哈希中的字段數量沒有限制,所以你可以在你的應用程序以不同的方式來使用哈希。

1、hset key field value:設置key中field的值

沒有field則寫入,有則覆蓋

2、hsetnx key field value:當鍵不存在時才設置值

使用hsetnx就不會覆蓋原值

3、hmset key field1 value1 ... fieldn valuen:設置多個鍵值

4、hget key field:獲取key中field的值

5、hmget key field1 ... fieldn:獲取多個值

6、hgetall key:獲取key中所有的鍵值

7、hdel key field:刪除key中的field

8、hlen key:返回key中的個數

9、hexists key field:判斷是否存在某個key

10、hkeys key:返回所有的鍵

11、hvals key:返回所有的值

12、hincyby key field value:增加整數值

 只能增加整數,不能增加小數。也可以增加負數。

13、hincrbyfloat key field value:增加小數

 


 

redis數據類型基本學完,下一篇學習事物、消息訂閱等。

完!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM