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數據類型基本學完,下一篇學習事物、消息訂閱等。
完!!!