目錄
- Redis五大資料類型
- 通用key操作
- String
-
- 基本操作
- 單資料操作與多資料操作
- 應用場景一
- 應用場景三
- Hash
-
- 基本操作
- 由來
- 資料結構
- 注意事項
- 應用場景
- List
-
- 基本操作
- 注意事項
- 應用場景一
- 應用場景二
- Set
-
- 基本操作
- 資料結構
- 為什麼要有set
- 為什麼set中的值具有唯一性
- 應用場景一
- 應用場景二
- 應用場景三
- Sorted_Set
-
- 基本操作
- 為什麼要有sorted_set
- 注意事項
- 應用場景一
- 應用場景二
Redis五大資料類型
Redis一共支援五種資料類型:String(字元串)、hash(哈希)、list(清單)、set(集合)和zset(sorted set有序集合)
String(字元串):Redis最基本的資料類型,一個鍵對應一個值,一個鍵值最大存儲512MB
Hash(哈希):hash是一個鍵值對的集合,是一個String類型的field和value的映射表,适合用于存儲對象
List(清單):是redis的簡單的字元串清單,按插入順序排序
Set(集合):是String字元串類型的無序集合,也不可重複
ZSet(sorted set 有序集合)是String類型的有序集合,也不可重複。有序集合中的每個元素都需要指定一個分數,根據分數對元素進行升序排序。
通用key操作
randomKey 随機傳回所有key中的某個
Exits key 判斷某個key是否存在,傳回1或0
del key 删除指定的key
rename key newKey 給指定key改名,如果新的key已經存在,則覆寫原來的key的值
renamenx key newkey 修改key的名稱,如果newkey已經存在,則傳回0(修改失敗),反之1(修改成功)
move key db(這裡用0,1,2..) 移動key到其他資料庫
ttl key 查詢key的有效期(-1:永久有效),傳回秒數
expire key 整型值 (秒為機關) 設定key生命周期
persist key 将某個key設定為永久有效
String
key-value形式
基本操作
# 增
set mykey "test" # 設定新值,如果已經存在則覆寫舊值
getset mycounter 0 # 先取值,再設定值(get xxx, set xxx xxx)
setex mykey 10 "hello" # 設定值的過期時間為10s,超過過期時間,值會銷毀
mset key1 "abc" key2 "123" # 批量增加
# 删
del mykey # 删除鍵---值,如果删除成功傳回1,否則傳回0(沒有這個鍵)
# 改
append mykey "hello" # 在原有值的後面追加,沒有就建立,傳回追加後的值的長度
incr c1 # 将值+1,沒有就建立,并設定初始值為1
decr c1 # 将值-1,沒有就建立,并設定初始值為-1
incrby c1 10 # 将值+10,沒有就建立,并設定初始值為10
decrby c1 10 # 将值-10,沒有就建立,并設定初始值為-10
setrange mykey 20 "dd" # 将第21和22位元組替換為"dd",長度不夠補0
# 查
exists mykey # 判斷該值是否存在,存在傳回1,否則傳回0
get mykey # 取值
strlen mykey # 擷取長度
ttl mykey # 擷取存活時間,-1表示永久存活
getrange mykey 1 20 # 擷取第2-20個位元組,超過了value的長度,則取第1個位元組後所有的值
mget key1 key2 # 批量取值
單資料操作與多資料操作

一條以上相同的指令數,多資料操作的執行時間要短
應用場景一
分庫分表之後主鍵怎麼保證唯一性
解決方案:
可以用redis中String類型中的incr、decr來實作,這個也不會帶來并發造成的資料影響,因為String在redis内部存儲預設是一個字元串,當遇到增減類incr、decr時會轉成數值型進行計算,redis所有的操作都是原子性的,采用單線程處理所有業務,指令是一個一個執行的,是以無需考慮并發帶來的資料影響。(數值有上線,java中long型資料最大值[- 2^63, 2^63 - 1])
incr key
incrby key increment
incrbyfloat key increament
decr key
decrby key increment
利用 redis 生成 id : 性能比較好,靈活友善,不依賴于資料庫。但是,引入了新的元件造成系統更加複雜,可用性降低,編碼更加複雜,增加了系統成本
也有其他解決方案:
UUID:不适合作為主鍵,因為太長了,并且無序不可讀,查詢效率低。比較适合用于生成唯一的名字的标示比如檔案的名字。
## 應用場景二 一定時間内的有效操作 例子:
- 海選投票,微信投票,每4小時投一票,
- 熱門每個商品維持三天,三天之後換下一個商品
- 熱點新聞
解決方案:
setex key seconds value
psetex key milliseconds value
redis控制資料的生命周期,通過資料是否失效控制業務行為,适用于所有具有時效性限定控制的操作
應用場景三
粉絲數,博文,關注數
解決方案:
- 在redis中為大V使用者設定使用者資訊,以使用者主鍵和屬性值作為key,背景設定定時重新整理政策
user:id:35067:fans 12210 user:id:35067:blogs 562 user:id:35067:focus 200
- 在redis中以josn格式存儲大V使用者資訊,定時重新整理(也可以用hash類型)
user:id:35067 {id:35067,name:王者 fans:12210,blogs:562,focus:200}
Hash
二維數組:
第一次元:數組
第二次元:連結清單
基本操作
hmset key field1 value [field2 value ...] # 設定一個或多個字段的值
hset key field value # 設定一個字段的值
hmget key field1 [fiedl2 ...] # 檢視一個或多個字段
hget key filed # 查詢一個字段
hgetall key # 檢視所有字段
hexists key field # 查詢是否有這個字段
hkeys key # 擷取所有字段
hlen key # 擷取字段數量
hvalues # 擷取所有的值
hdel key field1 [field2 ...] # 删除一個或多個字段
hincrby key field increment # 為一個字段增加指定值
hincrbyfloat key field increment # 為一個浮點數字段增加指定值
由來
String類型對于對象類資料的存儲和管理不友善,需要一個存儲空間儲存多個鍵值對資料,并對一系列存儲的資料進行編組,友善管理,典型應用存儲對象資訊
String類型存儲對象
hash類型存儲對象
資料結構
使用的哈希表結構實作資料存儲
注意事項
- hash類型下的value隻能存儲字元串,不允許存儲其他資料類型,不存在嵌套現象,如果資料未擷取到,對應的值未(nil)
- 每個hash可以存儲2^32-1個鍵值對
- hash類型十分貼近對象的資料存儲形式,并且可以靈活添加删除對象屬性,但hash設計初衷不是為了存儲大量對象而設計的,切記不可濫用,更不可以将hash作為對象清單使用
- hgetall操作可以擷取全部屬性,如果内部field過多,周遊整體資料效率就很低,有可能成為資料通路瓶頸
應用場景
電商網站購物車設計與實作
- 以客戶id作為key,每位客戶建立一個hash存儲結構存儲對應的購物車資訊
- 将商品編号作為field,購買數量作為value進行存儲
- 添加商品:追加全新的field與value
- 浏覽:周遊hash
- 更改數量:自增/自減,設定value值
- 删除商品:删除field
- 清空:删除key
List
雙向連結清單的結構
基本操作
BLPOP key1 [key2 ] timeout # 移出并擷取清單的第一個元素,如果清單沒有元素會阻塞清單直到等待逾時或發現可彈出元素為止
BRPOP key1 [key2 ] timeout # 移出并擷取清單最後一個元素,其他同 BLPOP
BRPOPLPUSH source destination timeout # 從清單中彈出一個值,将彈出的元素插入到另外一個清單中并傳回它; 如果清單沒有元素會阻塞清單直到等待逾時或發現可彈出元素為止。
LINDEX key index # 通過索引擷取清單中的元素
LINSERT key BEFORE|AFTER pivot value # 在清單的元素前或者後插入元素
LLEN key # 擷取清單長度
LPOP key # 移出并擷取清單第一個元素
RPOP key # 移出并擷取清單的最後一個元素
LPUSH key value1 [value2] # 将一個或多個值插入到清單頭部,沒有此清單則先建立
RPUSH key value1 [value2] # 将一個或多個值插入到清單尾部,沒有此清單則先建立
LPUSHX key value # 将一個值插入到已存在的清單頭部
RPUSHX key value # 将一個值插入到已存在的清單尾部
LRANGE key start stop # 擷取清單指定範圍内的元素
LREM key count value # 移除清單元素
LSET key index value # 通過索引設定清單元素的值
LTRIM key start stop # 删除清單中指定區間外的元素
DEL key # 删除清單
注意事項
- list中儲存得資料都是string類型的,資料總容量有限,最多2^32-1個元素
- list具有索引(0,-1)概念,但是操作資料時通常以隊列的形式進行入隊出隊操作,或以棧的形式進行入棧出棧操作
- 擷取全部資料操作結束索引設定未-1
- list可以對資料進行分頁操作,通常第一頁的資訊來自list,第二頁更多的資訊通過資料庫的形式加載
應用場景一
微信點贊,應用于具有操作先後順序的資料控制
key:使用者的id
value:點贊的人
點贊:rpush key value
取消點贊:lrem key count value
應用場景二
最新消息的展示,應用于有順序的消息聚集
企業營運中,系統将産生出大量的營運資料,如何保障多台伺服器記錄檔的統一順序輸出
解決方案:
- 依賴list的資料具有順序的特征對資訊進行管理
- 使用隊列模型解決多路資訊彙總合并問題
- 使用棧模型解決最新消息的問題
Set
value為nil的hash
基本操作
SADD key member1 [member2] # 向集合添加一個或多個成員,沒有此集合則建立
SCARD key # 擷取集合的成員數
SINTER key1 [key2] # 傳回給定所有集合的交集
SDIFF key1 [key2] # 傳回給定所有集合的差集
SUNION key1 [key2] # 傳回所有給定集合的并集
SDIFFSTORE destination key1 [key2] # 傳回給定所有集合的差集并存儲在 destination 中
SINTERSTORE destination key1 [key2] # 傳回給定所有集合的交集并存儲在 destination 中
SUNIONSTORE destination key1 [key2] # 所有給定集合的并集存儲在 destination 集合中
SISMEMBER key member # 判斷 member 元素是否是集合 key 的成員
SMEMBERS key # 傳回集合中的所有成員
SMOVE source destination member # 将 member 元素從 source 集合移動到 destination 集合
SPOP key # 移除并傳回集合中的一個随機元素
SRANDMEMBER key [count] # 傳回集合中一個或多個随機數
# 疊代集合中的元素
SSCAN key cursor [MATCH pattern] [COUNT count]
資料結構
底層使用了intset和hashtable兩種資料結構存儲的,intset我們可以了解為數組,hashtable就是普通的哈希表(key為set的值,value為null)
為什麼要有set
- 新的存儲需求:存儲大量的資料,在查詢方面提供更高的效率
- 需要的存儲結構:能夠儲存大量的資料,高校的内部存儲機制,便于查詢
-
set類型:與hash存儲結構完成相同,僅存儲鍵,不存儲值(nil),并且其中的值是不允許重複的
list有順序,連結清單查詢資料的效率很低,增删時間複雜度為O(1),查詢時間複雜度為O(n)
而hash增删查的時間複雜度都是O(1)
為什麼set中的值具有唯一性
因為如果出現相同的value就覆寫了
應用場景一
随機給使用者推薦幾類資料,應用于随機推薦類資訊檢索,例如熱點歌單推薦,推薦新聞,大V推薦
#随機擷取集合中指定數量的資料
srandmember key [count]
#随機擷取集合中的某個資料并将該資料移處集合
spop key [count]
應用場景二
共同關注,延申:可以根據共同關注或好友進行推薦好友的物品,應用于同類型不重複資料的合并操作
sdiff key1 key2 #差集
sinter key1 key2 #交集
sunion key1 key2 #并集
#求兩個集合的差、交、并集并存儲到指定集合中
sdiffstore 新key key1 [key2]
sinterstore 新key key1 [key2]
sunionstore 新key key1 [key2]
#将指定資料從原視集合中移動到目标集合中
smove source destination member
應用場景三
應用于同類型資料的快速去重
統計網站的PV(通路量),UV(獨立訪客),IP(獨立ip)
PV:網站被通路次數,可通過重新整理頁面提高通路量
UV:網站被不同使用者通路的次數,可通過cookie統計通路量,互相使用者切換ip位址,uv不變
IP:網站被不同IP位址通路的總次數,可通過IP位址統計通路量,相同的IP不同使用者通路,IP不敗你
解決方案:
- 利用set集合的資料去重特征,記錄各種通路資料
- 建立string類型資料,利用incr統計日通路量(PV)
- 建立set模型,記錄不同cookie數量(UV)
- 建立set模型,記錄不同IP數量(IP)
Sorted_Set
再set的存儲結構基礎上添加可排序字段
基本操作
ZADD key score1 member1 [score2 member2] # 向集合添加一個或多個成員,沒有此集合則建立
ZCARD key # 擷取有序集合的成員數
ZCOUNT key min max # 計算在有序集合中指定區間分數的成員數
ZINCRBY key increment member # 有序集合中對指定成員的分數加上增量 increment
ZINTERSTORE destination numkeys key [key ...] # 計算給定的一個或多個有序集的交集并将結果集存儲在新的有序集合 key 中
ZLEXCOUNT key min max # 在有序集合中計算指定字典區間内成員數量
ZRANGE key start stop [WITHSCORES] # 通過索引區間傳回有序集合指定區間内的成員
ZRANGEBYLEX key min max [LIMIT offset count] # 通過字典區間傳回有序集合的成員
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] # 通過分數傳回有序集合指定區間内的成員
ZRANK key member # 傳回有序集合中指定成員的索引
ZREM key member [member ...] # 移除有序集合中的一個或多個成員
ZREMRANGEBYLEX key min max # 移除有序集合中給定的字典區間的所有成員
ZREMRANGEBYRANK key start stop # 移除有序集合中給定的排名區間的所有成員
ZREMRANGEBYSCORE key min max # 移除有序集合中給定的分數區間的所有成員
ZREVRANGE key start stop [WITHSCORES] # 傳回有序集中指定區間内的成員,通過索引,分數從高到低
ZREVRANGEBYSCORE key max min [WITHSCORES] # 傳回有序集中指定分數區間内的成員,分數從高到低排序
ZREVRANK key member # 傳回有序集合中指定成員的排名,有序內建員按分數值遞減(從大到小)排序
ZSCORE key member # 傳回有序集中,成員的分數值
ZUNIONSTORE destination numkeys key [key ...] # 計算給定的一個或多個有序集的并集,并存儲在新的 key 中
ZSCAN key cursor [MATCH pattern] [COUNT count] # 疊代有序集合中的元素(包括元素成員和元素分值)
為什麼要有sorted_set
- 新需求:資料排序有利于資料的有效展示,需要提供一種可以根據自身特征進行排序的方式
- 需要的存儲結構:新的存儲模型,可以儲存可排序的資料
- score不是資料,是用來排序的
注意事項
- score儲存的資料存儲空間是64位
- score儲存的資料也可以是一個雙精度的double值,基于雙精度浮點數的特征,可能會丢失精度,使用要謹慎
- sored_set底層存儲還是基于set結構,是以資料不能重複,如果重複添加相同的資料,score值将會被反複覆寫,保留最後一次修改的結果(會傳回0,代表沒有進去,不代表沒有覆寫成功)
應用場景一
排名
#正向擷取該key中socre中的排名
zrank key member
#倒向擷取該key中socre中的排名
zrevrank key member
#擷取score值
zscore key member
#增加score值
zincrby key num member
應用場景二
任務權重管理
對于高優先級的任務要保障對其優先處理
解決方案:
- 對于帶有權重的任務,優先處理權重高的任務,采用score記錄權重即可