redis學習(二) redis資料結構介紹以及常用命令
redis資料結構介紹
我們已經知道redis是一個基於key-value資料儲存的資料結構資料庫,這裡的key指的是string型別,而對應的value則可以是多樣的資料結構。其中包括下面五種型別:
1.string 字串
string字串型別是redis最基礎的資料儲存型別。string是最基礎的一種資料型別,其可以拓展為某種特定型別,例如普通文字,json字串,二進位制資料等等。就本質上來說,接下來要介紹的hash,list,set等其內部最基礎的組成單位依然是string,只不過redis允許使用者以一種更加高效的方式處理某種資料結構的內部單元資料,這也是redis相對於memcached的一大優勢。
2.hash 雜湊
hash雜湊型別也是一種key-value形式的字典資料型別,儲存了key->value的對映,和redis本身一樣,其依然被限制為只允許字串型別作為key值。同時value並不支援巢狀的資料結構,而只能是字串型別(應該是為了保證redis設計的簡單性,以及高效能(巢狀結構越深,效率越低下),因此資料結構都不允許巢狀)。redis的hash型別適合儲存物件,比起json字串的形式,在僅僅訪問物件的部分屬性時,能夠避免不必要的cpu運算和資料傳輸,大大的提高了效率的同時也便於進行併發時的控制。
3.list 列表
list列表型別
4.set 集合
set集合型別擁有hash的部分特性,其內部實現採用的是value為空的hashTable(散列表),因此具有高效的查詢效率(O(1)時間複雜度),儲存的資料具有唯一性。set型別的常用操作除了通用的新增,刪除元素之外,還擁有集合型別獨有的獲得多個集合的交集,並集,差集的操作。
5.sorted set 有序集合
sorted set有序集合型別是和上述的set集合型別緊密相關的,顧名思義就是排序好了的集合。最大的區別在於儲存資料時,除了通用的value之外,還包括了score屬性作為排序的依據。有序集合同時擁有了list列表型別(有序)和set集合型別(value唯一)的特點。其和列表不同的是,有序集合型別內部實現採用的是hashTable(散列表)和skipList(跳躍表)。因此其訪問位於中間部分的資料效率也比較高(O(nlogn)時間複雜度 ),而list型別訪問中間部分元素的漸進意義下的時間複雜度則為O(n)。
天下沒有免費的午餐,在通過散列表和跳躍表具有較快的查詢速度的同時,同等資料量的情況下其消耗的記憶體相比雙向連結串列為基礎的list型別要高出不少,是一種空間換時間的做法,在決定使用有序集合時需要進行一定的權衡,避免不必要的系統資源浪費。
redis資料結構常用命令
redis提供了非常豐富的關於資料結構操作的各種命令。redis命令原則上不區分大小寫(這裡預設全部大寫),而key值區分大小寫
限於篇幅,這裡只介紹比較常用的命令,要想了解更多的細節,最好的辦法還是檢視redis提供的文件進行學習。
1.string 字串 常用命令
1.1 SET GET
SET 介面定義:SET key "value"
介面描述:儲存一個key-value鍵值對,如果之前key已經存在,覆蓋之前的value。
GET 介面定義:GET key
介面描述:通過key,返回對應的value,如果key不存在返回nil。
1.2 INCR
INCR 介面定義:INCR key
介面描述:將key對應的value增加1,並返回執行之後的資料(之前key不存在,預設value為0)。如果value無法解析為數字型別,則丟擲異常。
1.3 DECR
DECR 介面定義:DECR key
介面描述:將key對應的value減少1,並返回執行之後的資料(之前key不存在,預設value為0)。如果value無法解析為數字型別,則丟擲異常。
1.4 INCRBY DECRBY
INCRBY 介面定義: INCRBY key "increment"
介面描述: 將key對應的value減少引數increment,並返回執行之後的資料(之前key不存在,預設value為0)。如果increment/value無法解析為數字型別,則丟擲異常。
DECRBY 介面定義: DECRBY key "decrement"
介面描述: 將key對應的value減少引數decrement,並返回執行之後的資料(之前key不存在,預設value為0)。如果decrement/value無法解析為數字型別,則丟擲異常。
1.5 STRLEN
STRLEN 介面定義 : STRLEN key
介面描述:返回key對應的value的字串長度。
1.6 APPEND
APPEND 介面定義:APPEND key "value"
介面描述:在key對應的value後面新增字尾,並且返回執行之後value的字串長度。
1.7 string型別其它常用命令
字串型別的常用命令還有諸如MGET(同時獲取多個key的資料),MSET(同時設定多個key的資料),INCRBYFLOAT(增加一個浮點數值),DECRBYFLOAT(減少一個浮點數值),BITOP(位運算)等等。
2.hash 雜湊 常用命令
2.1 HSET HGET
HSET 介面定義: HSET key "field" "value"
介面描述:為key對應的Hash型別元素新增一個key-value鍵值對。
HGET 介面定義: HGET key "field"
介面描述:獲得key對應的Hash型別元素的某一field的value值。
2.2 HMSET HMGET (M代表multi,多選的含義)
HMSET 介面定義: HMSET key "field1" "value1" ["field2" "value2" "field3" "value3" ...]
介面描述:為key對應的Hash型別元素新增一個或多個key-value鍵值對。
HMGET 介面定義: HMGET key "field1" ["field2" "field3" ...]
介面描述:獲得key對應的Hash型別元素一個或多個field的value值。
2.3 HGETALL
HGETALL 介面定義: HGETALL key
介面描述:獲得key對應的Hash型別元素的所有key以及value值。
2.4 HEXISTS
HEXISTS 介面定義: HEXISTS key "field"
介面描述: 判斷key對應的Hash型別元素是否存在某一field,返回1代表存在,返回0代表不存在。
2.5 HDEL
HDEL 介面定義: HDEL key "filed1" ["field2","field3" ...]
介面描述:刪除key對應的Hash型別元素一個或多個field值,返回實際被刪除的field個數。
2.6 HLEN
HLEN 介面定義:HLEN key
介面描述: 獲得key對應的Hash型別元素當前存在的field的數量。
2.7 hash型別其它常用命令
hash型別的常用還有諸如HKEYS(獲得對應hash元素的所有field的值),HVALS(獲得對應hash元素的所有field的value值),HINCRBY(使對應hash元素的某一field的value值增加),HDECRBY(使對應hash元素的某一field的value值減少)等等。
3.List 列表型別 常用命令
3.1 LPUSH RPUSH
LPUSH 介面定義:LPUSH key "value1" ["value2","value3" ...]
介面描述:在對應key的列表元素頭部(left 左側)依次插入一個或多個數據節點,返回最終的列表長度。
RPUSH 介面定義 :RPUSH key "value1" ["value2","value3" ...]
介面描述:在對應key的列表元素尾部(right 右側)依次插入一個或多個數據節點,返回最終的列表長度。
3.2 LPOP RPOP
LPOP 介面定義:LPOP key
介面描述:返回對應key的列表元素頭部(left 左側)彈出(獲得元素,並且從列表中移除)第一個資料節點。
RPOP 介面定義:RPOP key
介面描述:返回對應key的列表元素尾部(right 右側)彈出(獲得元素,並且從列表中移除)第一個資料節點。
3.3 LLEN
LLEN 介面定義:LLEN key
介面描述:返回對應key的列表元素擁有的資料節點個數
3.4 LRANGE
LRANGE 介面定義:LRANGE key "start" "stop"
介面描述:返回對應key的列表元素 從start->stop下標之間的所有資料節點(和python一樣,支援負數下標(從末尾開始計算))。
3.5 LREM
LREM 介面定義:LREM key "count" "value"
介面描述:對應key的列表元素刪除(count個)值為value的資料節點。
潛規則:當count > 0時,從左到右匹配和刪除,count < 0時,從右到左匹配和刪除,count = 0時,刪除全部匹配的資料節點。
3.6 LINDEX
LINDEX 介面定義:LINDEX key "index"
介面描述:返回對應key的列表元素第index個數據節點,支援負數下標(從末尾開始計算)。
3.7 LSET
LSET 介面定義:LSET key "index" "value"
介面描述:將對應key的列表元素中位於index下標位置的資料賦值為value(如果下標越界,會丟擲異常)。
3.8 list列表型別其它常用命令
list型別的常用還有諸如LTRIM(擷取列表),LINSERT(向列表指定下標位置插入資料),RPOPLPUSH(將資料節點從一個列表轉移到另一個列表)等等。
4.set集合型別 常用命令
4.1 SADD SREM
SADD 介面定義:SADD key "member1" ["member2","member3" ...]
介面描述: 在對應key的集合元素中插入一到多個數據,返回實際被插入的資料個數(已經存在的資料不會被重複插入)。
SREM 介面定義:SREM key "member1" ["member2","member3" ...]
介面描述: 在對應key的集合元素中移除一到多個數據,返回實際被刪除的資料個數(不存在的資料不會被計算)。
4.2 SMEMBERS
SMEMBERS 介面定義:SMEMBERS key
介面描述:返回key對應的集合元素中所有資料。
4.3 SISMEMBER
SISMEMBER 介面定義:SISMEMBER key "member"
介面描述:判斷member是否存在於key對應的集合元素中,如果存在返回 1,如不存在返回 0。
4.4 SINTER SUNION SDIFF
SINTER 介面定義:SINTER "key1" ["key2","key3" ...]
介面描述:獲得一個或多個集合的交集。
SUNION 介面定義:SUNION "key1" ["key2","key3" ...]
介面描述:獲得一個或多個集合的並集。
SDIFF 介面定義:SDIFF "key1" ["key2","key3" ...]
介面描述:獲得一個或多個集合的差集,多個集合從左到右,進行運算。
4.5 SCARD
SCARD 介面描述:SCARD key
介面描述: 返回key對應的集合元素中資料的個數。
4.6 set型別其它常用命令
set型別的常用命令還有諸如SINTERSTORE,SUNIONSTORE,SDIFFSTORE(取得交集、並集、差集的結果,同時儲存為另一個集合),SRANDERMEMBER(從集合中隨機獲得元素),SPOP(從集合中隨機彈出元素)等等。
5.sorted set有序集合型別 常用命令
5.1 ZADD ZREM
ZADD 介面定義:ZADD key "score1" "member1" ["score2","member2","score3","member3" ...]
介面描述:在key對應的有序集合中插入一到多個 score->member 鍵值對,返回實際插入的資料(已經存在的資料不會被重複插入)。
ZREM 介面定義:ZREM key "member1" ["member2","member3" ...]
介面描述:在key對應的有序集合中刪除一到多個數據,返回實際被刪除的資料個數(不存在的資料不會被計算)。
5.2 ZSCORE
ZSCORE 介面定義:ZSCORE key member
介面描述:返回key對應的有序集合某一member對應score的值。
5.3 ZRANGE ZREVRANGE
ZRANGE 介面定義:ZRANGE key start stop
介面描述:key對應的有序集合按照score從小到大的順序,返回索引在start和stop之間的資料。
ZREVRANGE 介面定義:ZREVRANGE key start stop
介面描述:key對應的有序集合按照score從大到小的順序,返回索引在start和stop之間的資料。
5.4 ZINCRBY
ZINCRBY 介面定義:ZINCRBY key "increment" "member"
介面描述:key對應的有序集合的某一個member增加"incrment"(可以為負數),並且返回執行完畢的結果。
5.5 ZCARD
ZCARD 介面定義:ZCARD key
介面描述:返回key對應的有序集合中資料的數量。
5.6 zset型別其它常用命令
zset型別的常用命令還包括ZRANGEBYSCORE, ZREVRANGEBYSCORE(按照score範圍來進行順序查詢)、ZREM(移除集合內資料)等等。
6. redis資料結構相關常用命令總結
redis的資料結構相關命令還有很多,限於篇幅,上面只是簡要描述了我個人認為比較常用的命令。要想更加深入的理解這一部分內容,還是應該從官方文件,教學書籍入手,反覆的嘗試練習並且在工作中將其實踐。
redis的設計是很優雅的,命令介面大多是正交的,使用者可以很直觀的從命令的名稱、引數定義,快速的理解命令的使用方法。但是,我個人認為例如SRANDERMEMBER,SREM等命令設計的過於靈活,同一引數可以因為處於不同資料範圍而導致介面的行為完全不同,導致使用者被迫記住介面的一套獨有規則。這時倒不如設計多個不同的簡單介面分開實現功能,降低介面的靈活程度,畢竟有時候過於簡單反而會導致不必要的複雜性。