目錄
前言:
string
相關(guān)命令
內(nèi)部編碼
應(yīng)用場(chǎng)景
hash
相關(guān)命令
內(nèi)部編碼
應(yīng)用場(chǎng)景
list
相關(guān)命令
內(nèi)部編碼
應(yīng)用場(chǎng)景
set
相關(guān)命令
內(nèi)部編碼
應(yīng)用場(chǎng)景
Zset
相關(guān)命令
內(nèi)部編碼
應(yīng)用場(chǎng)景
漸進(jìn)式遍歷
前言:
? ? redis有多種數(shù)據(jù)類(lèi)型,常用的有五種,其他都是在特定場(chǎng)景下使用的數(shù)據(jù)類(lèi)型。具體需要使用時(shí)可以去redis官網(wǎng)中查閱。這篇文章將詳細(xì)介紹常用五種數(shù)據(jù)類(lèi)型。
string
? ? redis中的字符串,直接按照二進(jìn)制的方式存儲(chǔ)(不會(huì)做任何編碼轉(zhuǎn)換,怎么存就怎么?。?/p>
? ? 限制大小最大是512M(單線程操作都比較快)
注意:
? ??當(dāng)set key時(shí),如果是覆蓋了之前的value,那么之前的ttl(生存時(shí)間)也會(huì)失效,類(lèi)型可能也會(huì)改變(具體的內(nèi)部編碼)。
相關(guān)命令
ex:設(shè)置過(guò)期時(shí)間(單位:秒) px:設(shè)置過(guò)期時(shí)間(單位:毫秒)
NX:只有key不存在時(shí)才設(shè)置。如果key之前存在,設(shè)置不執(zhí)行 XX:只有key存在時(shí)才設(shè)置,如果key之前不存在,設(shè)置不執(zhí)行
SET key value [expiration EX seconds|PX milliseconds] [NX|XX] // 存儲(chǔ)數(shù)據(jù)
mset key [key...] // 同時(shí)存儲(chǔ)多個(gè)key
mget key [key...] // 同時(shí)獲取多個(gè)key
setNX key // 不存在時(shí)才能設(shè)置,存在則設(shè)置失敗
setEX key seconds value // 存儲(chǔ)key并且設(shè)置過(guò)期時(shí)間(秒)
psetEX key 毫秒 value // 存儲(chǔ)key并且設(shè)置過(guò)期時(shí)間(毫秒)
incr key // key + 1(key不存在則把這個(gè)key的value當(dāng)做0來(lái)使用)(操作value需要是整數(shù))
incrby key n // key + n
decr key // key - 1
decrby key n // key - n
incrbyfloat value // key + value(操作小數(shù))
append key value // 字符串拼接(返回值:拼接后的長(zhǎng)度。單位:字節(jié))
getrange key start end // 截取子字符串,左閉右閉,單位:字節(jié)(-1:倒數(shù)第一個(gè)元素)(漢字很可能切出來(lái)的不完整)
setrange key offset value // 替換字符串,返回值:替換后字符串長(zhǎng)度,單位:字節(jié)。針對(duì)不存在的key也可以操作,會(huì)把offset之前字節(jié)填充為0X00
strlen key // 獲得字符串長(zhǎng)度,單位:字節(jié)
內(nèi)部編碼
1)int 8字節(jié)/64位的整數(shù)。
2)embstr 壓縮字符串(對(duì)數(shù)據(jù)重新進(jìn)行編碼,占用更小的內(nèi)存空間),表示比較短的字符串。
3)raw 普通字符串,表示比較長(zhǎng)的字符串,單純使用字節(jié)數(shù)組存儲(chǔ)。
應(yīng)用場(chǎng)景
1)緩存
? ? 用戶(hù)先訪問(wèn)緩存,如果沒(méi)有數(shù)據(jù),則查找數(shù)據(jù)庫(kù),同時(shí)同步到redis中。
? ? 防止redis中數(shù)據(jù)量太大:1)redis中的key設(shè)置過(guò)期時(shí)間 。2)redis內(nèi)存不足時(shí),可以使用內(nèi)存淘汰策略。
2)統(tǒng)計(jì)數(shù)據(jù)
? ? redis中的數(shù)據(jù)異步的寫(xiě)入數(shù)據(jù)庫(kù)中,進(jìn)行數(shù)據(jù)分析統(tǒng)計(jì)。
3)存儲(chǔ)會(huì)話
? ? 分布式系統(tǒng)中,服務(wù)器集群共享一份會(huì)話信息,就可以判斷用戶(hù)的登錄狀態(tài)。(就算負(fù)載均衡把請(qǐng)求打到不同的服務(wù)器,也沒(méi)事)
4)手機(jī)驗(yàn)證碼
? ? 獲取驗(yàn)證碼間隔60秒,可以使用redis存儲(chǔ)驗(yàn)證碼,并且設(shè)置過(guò)期時(shí)間。
hash
? ? key-value的存儲(chǔ)方式,在redis中數(shù)據(jù)key被稱(chēng)為field。
相關(guān)命令
hset key field value [field value...] // 存儲(chǔ)鍵值對(duì)
hget key field // 獲取鍵值對(duì)
hexists key field 判斷fileld是否存在,返回值:1存在 0不存在
hdel key field [field...] // 刪除指定field,返回值:成功刪除的個(gè)數(shù)
hkeys key // 獲取哈希表中的所有field,時(shí)間復(fù)雜度:O(N)N哈希表中元素個(gè)數(shù)
hvals key // 獲取哈希表中所有value,時(shí)間復(fù)雜度:O(N)N哈希表中元素個(gè)數(shù)
hgetall key // 獲取hash表中所有field,value。時(shí)間復(fù)雜度:O(N)N哈希表中元素個(gè)數(shù)
hmget key field [field...] // 獲取多個(gè)field的value值
hstrlen key field // 計(jì)算value字符串長(zhǎng)度
hlen key // 獲取哈希表中元素個(gè)數(shù),不需要遍歷
hsetnx key field value // 不存在時(shí)才設(shè)置成功,存在則設(shè)置失敗
hincrby key field n // value + n(操作整數(shù))
hincrbyfloat key field n // value + n(操作小數(shù))
內(nèi)部編碼
ziplist hashtable
? ? 哈希表中的元素比較少,使用ziplist。如果元素比較多,使用hashtable表示。
? ? 哈希表中value長(zhǎng)度比較短,使用ziplist。如果value長(zhǎng)度比較長(zhǎng),使用hashtable。
注意:
? ? ziplist進(jìn)行讀寫(xiě)元素,速度比較慢。
應(yīng)用場(chǎng)景
? ? 作為緩存,可以存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)(對(duì)象)。
list
? ? 列表,內(nèi)部數(shù)據(jù)結(jié)構(gòu)可以認(rèn)為是雙端隊(duì)列。同時(shí)redis提供了阻塞版本的操作命令。
相關(guān)命令
lpush key value [value...] // 頭插法,返回值:list長(zhǎng)度
lrange key start stop // 范圍獲取數(shù)據(jù),前閉后閉,越界會(huì)盡量顯示list中的數(shù)據(jù),下標(biāo)支持負(fù)數(shù)
rpush key value [value...] // 尾插法,返回值:list長(zhǎng)度
rpushx key value // key存在才會(huì)入數(shù)據(jù),x:exists
lpop key // 頭刪,返回刪除的元素
rpop key // 尾刪,返回刪除的元素
lindex key index // 給定下標(biāo),獲取元素。O(N)
linsert key before|after pivot value // 指定基準(zhǔn)前或后插入數(shù)據(jù)。如果存在多個(gè)基準(zhǔn),從左往右找,找到第一個(gè)基準(zhǔn)值進(jìn)行插入。O(N)
llen key // 獲取list長(zhǎng)度
lrem key count value // 刪除指定元素,count為數(shù)量。count > 0從左往右刪count個(gè)。count < 0從右往左刪count個(gè)。count = 0刪除list中所有value
ltrim key start stop // 保留這個(gè)區(qū)間數(shù)據(jù),刪除其他所有數(shù)據(jù)。閉區(qū)間
lset key index value // 根據(jù)下標(biāo),修改元素。越界會(huì)報(bào)錯(cuò)
blpop key [key...] timeout // 如果隊(duì)列為空出數(shù)據(jù)則阻塞(阻塞期間redis可以執(zhí)行其他命令),只要某一個(gè)key不為空,則立刻出數(shù)據(jù)
brpop key [key...] timeout
內(nèi)部編碼
? ? 使用quicklist,結(jié)合了ziplist和linkedlist。每個(gè)鏈表節(jié)點(diǎn)中都是ziplist
應(yīng)用場(chǎng)景
1)作為數(shù)組,存儲(chǔ)多個(gè)元素
? ? 存儲(chǔ)mysql中表中的關(guān)聯(lián)字段。結(jié)構(gòu)化數(shù)據(jù)可使用hash存儲(chǔ)??梢詫㈥P(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行映射。
2)作為消息隊(duì)列(生產(chǎn)者消費(fèi)者模型)
? ? 可以使用阻塞版本的操作,實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型??蛻?hù)端和服務(wù)器之間的中間列表就可以做到一個(gè)緩沖功能。
注意:
? ? 如果使用for循環(huán)list,使用hgetall獲取每個(gè)hash中數(shù)據(jù),會(huì)存在多次網(wǎng)絡(luò)請(qǐng)求,可能會(huì)阻塞redis服務(wù)器。
? ? 解決方案:使用pipeline(流水線|管道)將多個(gè)redis命令合并為一條命令。進(jìn)行網(wǎng)絡(luò)通信。
? ? 如果list中數(shù)據(jù)量太大,范圍查找中間數(shù)據(jù),效率會(huì)比較低。
? ? 解決方案:將一個(gè)list分為多個(gè)list(類(lèi)似,分庫(kù)分表)
set
1)集合中的元素是無(wú)序的(變換順序還是原來(lái)那個(gè)set)
2)集合中的元素不能重復(fù)。
3)和list類(lèi)似,集合中的每個(gè)元素也是string類(lèi)型。
相關(guān)命令
sadd key member [member...] // 存儲(chǔ)元素,返回值添加成功了幾個(gè)元素
smembers key // 查詢(xún)集合中所有member
sismember key member // 判斷集合中member是否存在。1表示存在,0表示不存在
scard key // 返回集合中元素個(gè)數(shù)
spop key [count] // 隨機(jī)刪除set中的數(shù)據(jù),count可以指定一次刪除多個(gè)
smove source destination member // 從source中刪除,再插入到distination中
srem key member [member...] // 從set中刪除member
sinter key [key...] // 返回多個(gè)key的交集。O(N * M) N:最小集合元素個(gè)數(shù),M:最大集合元素個(gè)數(shù)
sinterstore destination key [key...] / 返回多個(gè)key集合數(shù)據(jù)存儲(chǔ)在destination集合中。返回交集元素個(gè)數(shù)。O(N)
sunion key [key...] // 返回多個(gè)key的并集。O(N)
sunionstore destination key [key...] // 將多個(gè)key的并集存儲(chǔ)在destination集合中。返回并集元素個(gè)數(shù)。O(N)
sdiff key [key...] // 返回多個(gè)Key的差集,前面key - 后面key,和key的順序有關(guān)聯(lián)。O(N)
sdiffstore destination key [key...] // 將差集存儲(chǔ)在destination集合中,返回差集元素個(gè)數(shù)。O(N)
內(nèi)部編碼
1)intset 當(dāng)元素均為整數(shù),并且元素個(gè)數(shù)不是很多。
2)hashtable 其他都是用哈希表存儲(chǔ)了。
應(yīng)用場(chǎng)景
1)保存用戶(hù)標(biāo)簽(用戶(hù)畫(huà)像)。大數(shù)據(jù)時(shí)代下,為每個(gè)用戶(hù)建立表標(biāo)簽(特點(diǎn)),方便服務(wù)器進(jìn)行用戶(hù)分析,進(jìn)行數(shù)據(jù)推送。(每個(gè)用戶(hù)都是相互獨(dú)立的存在)
2)計(jì)算用戶(hù)之間共同好友,可以做一些好友推薦。(可以使用集合間運(yùn)算)
3)爭(zhēng)對(duì)業(yè)務(wù)場(chǎng)景進(jìn)行去重。
Zset
1)value采用member和score的方式存儲(chǔ),內(nèi)部會(huì)根據(jù)每個(gè)member的score進(jìn)行排序。
2)有序集合。member必須唯一,score可以重復(fù)。底層默認(rèn)按照score升序排列。
相關(guān)命令
時(shí)間復(fù)雜度:O(logN) 底層是跳表,需要遍歷跳表找到指定位置進(jìn)行插入,保證集合有序
分?jǐn)?shù)相同按照member字典序排列
zadd key [NX | XX] [CH] [INCR] score member [score member...] // 返回值:有序集合添加元素的個(gè)數(shù) 時(shí)間復(fù)雜度:O(logN) NX:member不存在就添加 XX:member存在就修改 CH:修改返回值為修改集合member的個(gè)數(shù) INCR:指定member增加score
zrange key start stop [withscores] // 查找有序集合范圍中的member,withscores:同時(shí)可以查找score
zcard key // 返回集合中元素個(gè)數(shù)
zcount key min max // 返回指定分?jǐn)?shù)區(qū)間中元素個(gè)數(shù),使用(來(lái)設(shè)置開(kāi)區(qū)間。時(shí)間復(fù)雜度:O(logN)) 需要查找第一個(gè)start元素。inf:正無(wú)窮大 -inf:負(fù)無(wú)窮大
zrevrange key start stop [withscores] // 逆序查找出來(lái)的集合,按照分?jǐn)?shù)降序
zrangebyscore key min max [withscores] // 查找指定score區(qū)間中的member。時(shí)間復(fù)雜度:O(logN + M)M:max - min
zpopmax key [count] // 刪除并返回最高的count個(gè)元素。返回值:被刪除的member和score。如果存在多個(gè)分?jǐn)?shù)最大的元素,只刪除member字典序大的數(shù)據(jù)。時(shí)間復(fù)雜度:O(logN * M)需要找到每個(gè)元素進(jìn)行刪除,底層使用通用的刪除函數(shù)
bzpopmax key [key...] timeout // 帶有阻塞的彈出,如果為空就會(huì)阻塞。和blpop機(jī)制一樣。時(shí)間復(fù)雜度:O(logN)需要找到數(shù)據(jù)
zpopmin key [count] // 刪除score最小的count個(gè)元素。時(shí)間復(fù)雜度:O(logN + M)
bzpopmin key [key...] timeout // 帶有阻塞的彈出
zrank key member // 返回member的下標(biāo),從左往右由0開(kāi)始。時(shí)間復(fù)雜度:O(logN)
zrevrank key member // 返回member下標(biāo),從右往左由0開(kāi)始
zscore key member // 根據(jù)member找到score。時(shí)間復(fù)雜度:O(1) redis在這里做了特殊優(yōu)化
zrem key member [member...] // 刪除指定的member。時(shí)間復(fù)雜度:O(logN * M) 需要一個(gè)一個(gè)刪除。M命令中member的個(gè)數(shù)
zremrangebyrank key start stop // 根據(jù)下標(biāo)進(jìn)行范圍刪除。時(shí)間復(fù)雜度:O(logN + M) M:stop - start
zremrangebyscore key min max // 根據(jù)score進(jìn)行范圍刪除。(可設(shè)置開(kāi)區(qū)間。時(shí)間復(fù)雜度:O(logN + M) M:max - min
zincrby key increment member // 指定member對(duì)score + increment。時(shí)間復(fù)雜度:O(logN)
zinterstore destination numkeys key [key...] [weights weight [weight...]] [aggregate < sum | min | max] // 求多個(gè)key的交集存在destination中。weights:指定key的權(quán)重,最終結(jié)果會(huì)將key中所有score * weight作為結(jié)果。aggregate:交集中score相同的處理選擇。時(shí)間復(fù)雜度:O(logM * M)近似值,M:最終結(jié)果有序集合元素個(gè)數(shù)
zunionstore destination numkeys key [key...] [weights weight [weight...]] [aggregate < sum | min | max] // 用法和上述一致
內(nèi)部編碼
1)ziplist 如果有序集合中元素較少,或者單個(gè)元素體積較小。
2)skiplist 如果有序集合中元素較多,或者單個(gè)元素體積很大。跳表:查詢(xún)?cè)貢r(shí)間復(fù)雜度log(N)
應(yīng)用場(chǎng)景
? ? 排行榜系統(tǒng)。微博熱搜,游戲天梯排行,成績(jī)排行。
? ? 微博熱搜,可以根據(jù)多維度數(shù)據(jù)進(jìn)行加權(quán)計(jì)算,得到最終的綜合得分(熱度)。每個(gè)維度使用有序集合存儲(chǔ)(id, score)然后進(jìn)行集合間運(yùn)算,就可以使用加權(quán)計(jì)算出最終的熱度排行。
漸進(jìn)式遍歷
pattern:key的匹配模式
count:建議命令一次遍歷幾個(gè)元素,具體是幾個(gè)是在count上下浮動(dòng)
type:指定遍歷key的value類(lèi)型
cursor:光標(biāo),字符串。下次開(kāi)始遍歷的位置
scan cursor [MATCH pattern] [COUNT count] [TYPE type]
注意:
? ? 漸進(jìn)式遍歷,在遍歷過(guò)程中,不會(huì)在服務(wù)器這邊存儲(chǔ)任何狀態(tài)信息。此處遍歷是可以隨時(shí)終止的,不會(huì)對(duì)服務(wù)器產(chǎn)生任何副作用。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-670024.html
? ? 漸進(jìn)式遍歷雖然解決了阻塞問(wèn)題,但如果遍歷過(guò)程中鍵有所變化(增加,修改,刪除),可能導(dǎo)致遍歷時(shí)鍵的重復(fù)遍歷或者遺漏。開(kāi)發(fā)中務(wù)必需要考慮。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-670024.html
到了這里,關(guān)于redis常用五種數(shù)據(jù)類(lèi)型詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!