Redis(Remote Dictionary Service) --- 遠(yuǎn)程字典服務(wù)
Redis的五種數(shù)據(jù)結(jié)構(gòu):string(字符串)节仿,list(列表)节预,hash(哈希)羊赵,set(集合)漏麦,zset(有序集合)
Redis之所以稱為遠(yuǎn)程字典服務(wù)是因?yàn)樗乃袛?shù)據(jù)結(jié)構(gòu)都是由K-V形式組成的骗灶,以唯一的key作為名稱,來(lái)獲取對(duì)應(yīng)的value系草。
注意:不同的數(shù)據(jù)結(jié)構(gòu)通熄,實(shí)際上就是不同的Value結(jié)構(gòu)。
String:
Redis的字符串是動(dòng)態(tài)字符串悄但,可以修改棠隐,采用預(yù)分配冗余空間的方式來(lái)減少內(nèi)存的頻繁分配。
擴(kuò)容規(guī)則:小于1MB擴(kuò)大一倍檐嚣,大于1MB每次擴(kuò)大1MB助泽,字符串最大的長(zhǎng)度為512MB。
#添加操作 --- 可覆蓋
set key value
set name codehole
#取值操作
get key
get name
#判斷是否存在嚎京,如果存在返回1嗡贺,如果不存在返回0
exists key
exists name
#批量添加
mget key1 value1 key2 value2 key3 value3
mset name1 boy name2 girl name3 unknown
#批量獲取
mget key1 key2 key3
mget name1 name2 name3
#過(guò)期時(shí)間設(shè)置 --- 相當(dāng)于定時(shí)刪除
expire key time (以秒為單位)
expire name 5 (key為name的元素在5秒后過(guò)期)
#set+expire的等價(jià)形式 setex
setex key time value
setex name 5 codehole
#創(chuàng)建操作 如果setnx的key已經(jīng)存在則返回0,不進(jìn)行任何操作鞍帝,不覆蓋原值诫睬。如果key不存在,則等價(jià)于正常的set創(chuàng)建帕涌,返回值為1
setnx key value
setnx name codehole
#返回字符串的長(zhǎng)度 ---strlen
strlen key
strlen name
#value為數(shù)值時(shí)的自增操作---incr摄凡,incrby
incr key (返回值為key對(duì)應(yīng)的value+1)
incrby key num (返回值為key對(duì)應(yīng)value+num)
#注意:自增范圍不能超過(guò)signed long,num可以為負(fù)數(shù)蚓曼,相當(dāng)于減法
List:
Remote Dictionary Service中的列表其實(shí)是由鏈表形成的亲澡,本鏈表是雙向鏈表。
注意:插入和刪除的時(shí)間復(fù)雜度為O(1)纫版,索引定位時(shí)間復(fù)雜度為O(n)床绪。
由Redis的雙向鏈表形成的兩種Redis數(shù)據(jù)結(jié)構(gòu)----隊(duì)列和棧
隊(duì)列:右進(jìn)左出,先進(jìn)先出,利用list語(yǔ)句中的rpush癞己,lpop實(shí)現(xiàn)膀斋。
注意:添加元素時(shí),均為從右邊進(jìn)入痹雅。
堆棧:右進(jìn)右出仰担,先入先出,利用list語(yǔ)句中的rpush练慕,rpop實(shí)現(xiàn)惰匙。
#添加語(yǔ)句--rpush
rpush key value1 value2 value3
rpush books java python golang
#左刪除元素---lpop key
lpop key #彈出第一個(gè)從左邊刪除的元素
lpop books
#右刪除元素---rpop key
rpop key #彈出第一個(gè)從右邊刪除的元素
rpop books
由于Redis中l(wèi)ist的數(shù)據(jù)結(jié)構(gòu)為雙向鏈表,所以無(wú)法通過(guò)索引來(lái)進(jìn)行定位铃将,只能通過(guò)遍歷的方式,這樣時(shí)間復(fù)雜度為O(n)哑梳,在數(shù)據(jù)量很大的時(shí)候劲阎,操作時(shí)間較長(zhǎng),稱為慢操作鸠真,慢操作包含以下內(nèi)容:
#通過(guò)索引取值---lindex
#注意:雖然說(shuō)是通過(guò)索引取值悯仙,但是它無(wú)法直接取值,而是通過(guò)遍歷的方式
#這里還需要注意的是吠卷,index是可以為負(fù)數(shù)的锡垄,-1為倒數(shù)第一個(gè)元素,-2為倒數(shù)第二個(gè)元素
lindex key index
lindex books 0 #獲取key為books的第0個(gè)元素
#獲取區(qū)間內(nèi)索引的值---ltrim
#定義了一個(gè)區(qū)間[start_index祭隔,end_index]货岭,對(duì)區(qū)間內(nèi)的值進(jìn)行保留,其余的全部刨除
ltrim key start_index end_index
ltrim books 1 0 #當(dāng)start_index大于end_index時(shí)疾渴,相當(dāng)于清空所有元素
#獲取列表的長(zhǎng)度 ---llen
llen key
llen books
#讀取區(qū)域內(nèi)的列表內(nèi)容千贯,區(qū)域?yàn)閇start_index,end_index]
lrange key start_index end_index
lrange books 0 -1 #0到-1為遍歷所有的元素
Dict:
Redis的dict通俗來(lái)講就是字典形式搞坝,內(nèi)部存儲(chǔ)許多鍵值對(duì)搔谴,與廣義上的字典不同的是,Redis的字典只能存儲(chǔ)字符串桩撮,而且與Java中的HashMap采用了不一樣的hash方式敦第。
注意:對(duì)于正常的字典來(lái)說(shuō),rehash的方式是直接將全部舊的哈希表的內(nèi)容遷移到新表之中店量,但是對(duì)于Redis來(lái)說(shuō)芜果,像rehash這種耗時(shí)的操作或許會(huì)導(dǎo)致線程阻塞,從而導(dǎo)致服務(wù)器宕機(jī)垫桂,所以Redis采用了一種不同的rehash方式---漸進(jìn)式的rehash
漸進(jìn)式rehash:這種rehash的方式會(huì)在rehash的同時(shí)师幕,保留新舊兩個(gè)rehash結(jié)構(gòu),查詢時(shí)會(huì)同時(shí)查詢兩個(gè)hash結(jié)構(gòu),在后續(xù)的定時(shí)任務(wù)以及hash操作只能中霹粥,循序漸進(jìn)的將舊的hash內(nèi)容慢慢遷移到新的hash中灭将,當(dāng)全部遷移結(jié)束之后,刪除舊的hash后控,用新的hash取而代之庙曙。
hash功能:存儲(chǔ)用戶信息,優(yōu)點(diǎn)是可以分字段存儲(chǔ)浩淘,缺點(diǎn)是存儲(chǔ)的消耗量很大首启。
#添加鍵值對(duì) ---hset
#注意:只能添加一對(duì)鍵值對(duì),不能像rpush一樣添加多個(gè)破讨,想要添加多個(gè)需要使用hmset
hset key hashkey hashvalue
hset books java "think in java"
#一次性添加多個(gè)鍵值對(duì) ---hmset
hmset key hashkey1 hashvalue1 hashkey2 hashvalue2...
hmset books java "think in java" python "python games" #注意字段中有括號(hào)時(shí)碑定,需要加上雙引號(hào)
#讀取字典全部鍵值對(duì) --- hgetall
hgetall key
hgetall books
#讀取鍵值對(duì) ---hget
#和hset一致,只能夠讀取一個(gè)hashkey所對(duì)應(yīng)的value署惯,想要讀取多個(gè)需要使用hmget
hget key hashkey
hget book java
#讀取多個(gè)鍵值對(duì) ---hmget
hmget key hashkey1 hashkey2 hashkey3
#讀取dict中的數(shù)據(jù)個(gè)數(shù) ---hlen
hlen key
hlen book
#刪除字典中的鍵值對(duì) ---hdel
hdel key hashkey
hdel book java
#自增以及加法 ---hincrby
#需要注意的是左驾,雖然dict中的值都是字符串形式,但是可以對(duì)value中以字符串形出現(xiàn)的數(shù)據(jù)量進(jìn)行加法
#注意:如果檢測(cè)到value值非數(shù)字极谊,則會(huì)報(bào)錯(cuò)诡右,如果hashkey不存在,則會(huì)建立對(duì)應(yīng)的hashkey轻猖,值為num
hincrby key hashkey num
hincrby person age 1
Set:
Redis中的set數(shù)據(jù)類型其實(shí)也是一種鍵值對(duì)的形式帆吻,內(nèi)部是無(wú)序的,唯一的鍵值對(duì)咙边,只不過(guò)set集合中的所有的value都是null猜煮。set結(jié)構(gòu)可以用來(lái)存儲(chǔ)活動(dòng)中獎(jiǎng)的用戶ID,因?yàn)橛腥ブ氐墓δ苎撸梢员WC一個(gè)用戶不會(huì)中獎(jiǎng)兩次友瘤。
#添加元素 ---sadd
#注意:在添加元素時(shí),會(huì)自動(dòng)監(jiān)測(cè)元素的key是否已經(jīng)存在在set中檐束,如果已經(jīng)存在辫秧,則會(huì)返回0且不再添加,如果不存在則會(huì)返回1被丧,并且將其添加到集合中
sadd key setkey1 setkey2 setkey3
sadd books python
#sadd與rpush相同盟戏,可以添加多個(gè)元素
sadd books python java c++ golang
#讀取顯示集合中所有元素
#讀取的順序可能與存入的順序不同,因?yàn)閟et是無(wú)序的
smembers key
#查詢是否存在 ---sismember
#如果存在則返回1甥桂,如果不存在則返回0
sismember key setkey
sismember book java
# 獲得集合的長(zhǎng)度 ---scard
#相當(dāng)于list中的llen柿究,hash中的hlen
scard key
scard book
#刪除集合中的元素 ---srem
srem key setkey
srem book java
#隨機(jī)彈出并刪除一個(gè)元素 ---spop
spop key
spop book
Zset:
Redis中的Zset應(yīng)該是最有特色的數(shù)據(jù)結(jié)構(gòu)了,它的中文名稱是有序列表黄选,他既有集合的唯一性蝇摸,又將無(wú)序性去掉婶肩,采用score的方式來(lái)排序,它的內(nèi)部是由跳表構(gòu)成的貌夕,跳表我們以后再說(shuō)律歼。
Zset的功能很多,他可以存儲(chǔ)粉絲列表啡专,還能存儲(chǔ)學(xué)生成句险毁,并且按照所需的方式排列。
#添加元素 ---zadd
#zadd和sadd,rpush一樣可以一次性添加多個(gè)元素
#而字符串中的set和字典中的hset則不能们童,需要使用mset和hmset
zadd key score value
zadd books 9.0 "think in java"
#按照成績(jī)排名輸出 --- zrange
#幾乎與列表中的lrange相同畔况,不再贅述
zrange key start_index end_index
zrange books 0 -1
#按照成績(jī)排名的逆序進(jìn)行輸出 --- zrevrange
zrevrange key start_index end_index
zrevrange books 0 -1
#計(jì)算有序集合的長(zhǎng)度 ---zcard
#與scard的功能用法相同
zcard key
zcard books
#獲取指定value的score ---zscore
#返回值為value所對(duì)應(yīng)的分?jǐn)?shù),分?jǐn)?shù)內(nèi)部的存儲(chǔ)形式為double所以存在小數(shù)點(diǎn)的精度問(wèn)題
zscore key value
zscore book java
#獲取某元素在有序列表中的排名 ---zrank
#返回值為對(duì)應(yīng)的排名慧库,需要特別注意的是跷跪,第一位是0,從低到高排序
zrank key value
zrank book java
#獲取某元素在有序列表中的排名 ---zrevrank
#從高到低排序
zrevrank key value
zrevrank book java
#分值區(qū)間內(nèi)遍歷有序列表 ---zrangebyscore
# inf代表infinite 代表無(wú)窮大 順序?yàn)閺男〉酱?zrangebyscore key lowscore highscore
zrangebyscore book 0 8.9
zrangebyscore book 0 8.9 withscores
#刪除元素 ---zrem
zrem key value
zrem book java
#給成員增加指定分?jǐn)?shù) ---zincrby
zincrby key num value
zincrby book 1 java
#返回在指定分?jǐn)?shù)區(qū)域內(nèi)的元素個(gè)數(shù) ---zcount
zcount key lowscore highscore
zcount book 8 9
#刪除指定成績(jī)區(qū)間的元素 ---zremrangebyscore
zremrangebyscore key lowscore highscore
zremrangebysocre book 8 9
#刪除指定排名區(qū)間的元素 ---zremrangebyrank
zremrangebyrank key lowrank highrank
zremrangebyrank book 1 2