Redis學習筆記之基本資料結構
Redis基礎資料結構
Redis有5種基本資料結構:String(字串)、list(列表)、set(集合)、hash(雜湊)、zset(有序集合)
字串string
字串型別是Redis的value最簡單的資料結構,類似與Java語言中的ArrayList(數字列表),不過在Redis裡String是一種動態字串
Redis裡的String採用預分配冗餘空間的方法
set & get
>set keyname test OK >get keyname test //key如果存在就返回0 >setnx keyname test 0 >exists keyname >del keyname 1 //批量設定 >mset key1 test1 key2 test2 OK //批量獲取 >mget key1 key2 1) test1 2) test2
key過期
//設定5s後過期
>expire keyname 5
//setex是expire和set的複合寫法
>setex keyname 5 test
OK
//5s後查詢
>get keyname
NULL
計數
ps:value為數字的情況,可以使用incr和incrby計數
>set num 10 OK //incr預設加1 >incr num 11 //incrby後面要加上數字 >incrby num ERR wrong number of arguments for 'incrby' command //正確計數 >incrby num 5 16
列表list
下面介紹一下redis的另外一種資料結構list
前面我們說redis裡的string類似與java語言裡面的ArrayList,則redis裡的列表就類似於LinkList(連結串列),連結串列一個特別就是更新和新增特別快,查詢索引慢。
為什麼說類似與linklist?因為redis的list並非和linklist一樣,它其實是一種快速列表(quicklist)的形式,列表結構如圖:
這裡要介紹一下壓縮列表(ziplist)了,壓縮列表是什麼?其實就是連續的記憶體空間
從圖可以看出快速列表其實就是由壓縮列表和雙向的指標組成,不過我們知道連結串列是兩個指標的,也就是prev和next執行,這就是快速列表和linklist的一個不同點了。
PS:然後redis設計時,為什麼改成雙向指標?假如和連結串列一樣,用兩個指標prev、next,同樣可以實現遍歷,不過雙向指標有一個很明顯的優點,就是佔用的記憶體空間就相對少了。
佇列和棧
/* 佇列:First in first out */
//加兩個value
>rpush keynames key1 key2
2
//計算
>llen keynames
2
>lpop keynames
key1
>lpop keynames
key2
//rpush會自動過期的
>rpop keynames
NULL
/* 棧:First in last out */
//同樣,加兩個元素
>rpush keynames key1 key2
2
>rpop keynames
key2
>rpop keynames
key1
字典hash
Redis的字典類似與java語言的hashmap,也是無序的二維結構,也即陣列加列表的結構。這是redis字典和hashmap類似的地。
然後也有不同,比如rehash,重新整理字典操作,hashmap是全部熱hash,當字典足夠多時,效能不是很好的,所以redis進行改造,採用漸進式的方式,為什麼說是漸進式?因為redis不會全部reload,而是儲存新舊兩個字典,然後採用定時任務,將舊hash的資料搬到新的hash,搬後在回收hash記憶體空間
字典(hash)的陣列加連結結構:
>hset keynames key1 "test1"
1
>hset keynames key2 "test2"
1
//批量set
>hmset keynames key1 "test1" key2 "test2"
OK
//獲取key1的值
>hget keynames key1
test1
//獲取hash為keynames的長度
>hlen keynames
2
//獲取全部
>hgetall keynames
1) key1
2) test1
3) key2
4) test2
集合set
redis的set和java語言中的hashset型別,是一種無序唯一的。
>sadd keynames key1
1
//key1已經加過了,所以返回1
>sadd keynames key1 key2
1
>smembers keynames
1) key2
2) key1
//查詢某個key是否存在,相當與contains
>sismember keynames key1
1
//相當於count
>scard keynames
2
//隨意彈出key1
>spop keynames
key1
有序集合zSet
有序集合是redis裡比較有特色的,它類似於SortedSet和HashMap的組合。其內部實現是一種被稱作跳躍列表的資料結構。有序集合一方面它就是一個set,所以每個元素都是唯一的,然後它可以給每個value賦值一個score,再根據這個score進行排序,score就相當於一個許可權排序的標識。
ps:因為這個原因,有序集合可以被用來儲存粉絲資訊,value值是粉絲id,score是關注時間
//9.0是score也就是權重
>zadd keyname 9.0 math
1
>zadd keyname 9.2 history
1
//順序
>zrange keyname 0 -1
1) history
2) math
//逆序
>zrevrange keyname 0 -1
1) math
2) history
//相當於count()
>zcard keyname
2
獲取指定key的score
>zscore keyname math
9
跳躍列表 TODO