Redis 數據結構
String 字符串
基本命令表
命令 | 執行效果 | 時間復雜度 |
---|---|---|
set key value [key value…] | 設置 key 的值是 value | O(k), k 是鍵個數 |
get key | 獲取 key 的值 | O(1) |
del key [key …] | 刪除指定的 key | O(k), k 是鍵個數 |
mset key value [key value …] | 批量設置指定的 key 和 value | O(k), k 是鍵個數 |
mget key [key …] | 批量獲取 key 的值 | O(k), k 是鍵個數 |
incr key | 指定的 key 的值 +1 | O(1) |
decr key | 指定的 key 的值 -1 | O(1) |
incrby key n | 指定的 key 的值 +n | O(1) |
decrby key n | 指定的 key 的值 -n | O(1) |
incrbyfloat key n | 指定的 key 的值 +n(浮點數) | O(1) |
append key value | 指定的 key 的值追加 value | O(1) |
strlen key | 獲取指定 key 的值的長度 | O(1) |
setrange key offset value | 覆蓋指定 key 的從 offset 開始的部分值 | O(n),n 是字符串長度,通常視為 O(1) |
getrange key start end | 獲取指定 key 的從 start 到 end 的部分值 | O(n),n 是字符串長度,通常視為 O(1) |
SET 命令
將 string 類型的 value 設置到 key 中。如果 key 之前存在,則覆蓋,無論原來的數據類型是什么。之前關于此 key 的 TTL 也全部失效。
SET 命令支持多種選項來影響它的行為:
- EX seconds——使用秒作為單位設置 key 的過期時間。
- PX milliseconds——使用毫秒作為單位設置 key 的過期時間。
- NX——只在 key 不存在時才進行設置,即如果 key 之前已經存在,設置不執行。
- XX——只在 key 存在時才進行設置,即如果 key 之前不存在,設置不執行。
注意:由于帶選項的 SET 命令可以被 SETNX、SETEX、PSETEX 等命令代替,所以之后的版本中,Redis 可能進行合并。
Hash 哈希
幾乎所有的主流編程語言都提供了哈希(hash)類型,它們的叫法可能是哈希、字典、關聯數組、映射。在 Redis 中,哈希類型是指值本身又是一個鍵值對結構,形如 key = “key”,value = { {field1, value1 }, …, {fieldN, valueN } }。
哈希類型中的映射關系通常稱為 field-value,用于區分 Redis 整體的鍵值對(key-value),注意這里的 value 是指 field 對應的值,不是鍵(key)對應的值,請注意 value 在不同上下文的作用。
基本命令表
命令 | 執行效果 | 時間復雜度 |
---|---|---|
hset key field value | 設置值 | O(1) |
hget key field | 獲取值 | O(1) |
hdel key field [field …] | 刪除 field | O(k), k 是 field 個數 |
hlen key | 計算 field 個數 | O(1) |
hgetall key | 獲取所有的 field-value | O(k), k 是 field 個數 |
hmget key field [field …] | 批量獲取 field-value | O(k), k 是 field 個數 |
hmset key field value [field value …] | 批量設置 field-value | O(k), k 是 field 個數 |
hexists key field | 判斷 field 是否存在 | O(1) |
hkeys key | 獲取所有的 field | O(k), k 是 field 個數 |
hvals key | 獲取所有的 value | O(k), k 是 field 個數 |
hsetnx key field value | 設置值,但必須在 field 不存在時才能設置成功 | O(1) |
hincrby key field n | 對應 field-value +n | O(1) |
hincrbyfloat key field n | 對應 field-value +n(浮點數) | O(1) |
hstrlen key field | 計算 value 的字符串長度 | O(1) |
注意:
在使用 HGETALL 時,如果哈希元素個數比較多,會存在阻塞 Redis 的可能。如果開發人員只需要獲取部分 field,可以使用 HMGET,如果一定要獲取全部 field,可以嘗試使用 HSCAN 命令,該命令采用漸進式遍歷哈希類型。
List 列表
列表是一種比較靈活的數據結構,它可以充當棧和隊列的角色,在實際開發上有很多應用場景。
特點:
- 第一、列表中的元素是有序的,這意味著可以通過索引下標獲取某個元素或者某個范圍的元素列表,例如要獲取第 5 個元素,可以執行
lindex user:1:messages 4
;獲取倒數第 1 個元素,lindex user:1:messages -1
即可。 - 第二、區分獲取和刪除的區別,例如
lrem 1 b
是從列表中把從左數遇到的前 1 個 b 元素刪除,這個操作會導致列表的長度變化;但執行lindex 4
只會獲取元素,列表長度不變。 - 第三、列表中的元素是允許重復的。
阻塞版本命令
blpop 和 brpop 是 lpop 和 rpop 的阻塞版本,和對應非阻塞版本的作用基本一致,除了:
- 在列表中有元素的情況下,阻塞和非阻塞表現是一致的。但如果列表中沒有元素,非阻塞版本會立即返回 nil,但阻塞版本會根據 timeout 阻塞一段時間,期間 Redis 可以執行其他命令,但執行該命令的客戶端會表現為阻塞狀態。
- 命令中如果設置了多個鍵,那么會從左向右進行遍歷鍵,一旦有一個鍵對應的列表中可以彈出元素,命令立即返回。
- 如果多個客戶端同時對一個鍵執行 pop,則最先執行命令的客戶端會得到彈出的元素。
列表不為空時:
lpop user:1:messages 得到 x 元素
blpop user:1:messages 得到 x 元素
兩者行為一致列表為空時,且 5 秒內沒有新元素加入:
lpop user:1:messages 立即得到 nil
blpop user:1:messages 5 執行命令 5 秒后得到 nil
兩者行為不一致列表為空時,且 5 秒內有新元素加入:
lpop user:1:messages 立即得到 nil
blpop user:1:messages 5 執行命令,直到新元素加入,得到新元素
兩者行為不一致
基本列表命令
操作類型 | 命令 | 時間復雜度 |
---|---|---|
添加 | rpush key value [value …] | O(k),k 是元素個數 |
lpush key value [value …] | O(k),k 是元素個數 | |
linsert key before/after pivot value | O(n),n 是 pivot 距離頭尾的距離 | |
查找 | lrange key start end | O(s+n),s 是 start 偏移量,n 是 start 到 end 的范圍 |
lindex key index | O(n),n 是索引的偏移量 | |
llen key | O(1) | |
刪除 | lpop key | O(1) |
rpop key | O(1) | |
lrem key count value | O(k),k 是元素個數 | |
ltrim key start end | O(k),k 是元素個數 | |
修改 | lset key index value | O(n),n 是索引的偏移量 |
阻塞操作 | blpop key [key …] timeout | O(1) |
brpop key [key …] timeout | O(1) |
Set 集合
集合類型也是保存多個字符串類型的元素的,但和列表類型不同的是,集合中:1)元素之間是無序的;2)元素不允許重復。一個集合中最多可以存儲 2^32 - 1 個元素。Redis 除了支持集合內的增刪查改操作,同時還支持多個集合取交集、并集、差集,合理地使用好集合類型,能在實際開發中解決很多問題。
SPOP
從 set 中刪除并返回一個或者多個元素。注意,由于 set 內的元素是無序的,所以取出哪個元素實際是未定義行為,即可以看作隨機的。
基本命令表
命令 | 描述 | 時間復雜度 |
---|---|---|
SADD key member [member …] | 向集合添加一個或多個成員 | O(1)(單個元素),批量添加時為 O(k),k 是成員個數 |
SCARD key | 獲取集合的成員數 | O(1) |
SISMEMBER key member | 判斷 member 元素是否是集合 key 的成員 | O(1) |
SMEMBERS key | 返回集合中的所有成員 | O(N),其中 N 為集合中的成員數量 |
SPOP key [count] | 移除并返回集合中的一個隨機成員;如果指定了 count,則返回多個隨機成員 | O(1)(單個元素),指定 count 時為 O(count) |
SREM key member [member …] | 從集合中移除一個或多個成員 | O(N),其中 N 為被刪除的成員數量 |
SMOVE source destination member | 將 member 元素從 source 集合移動到 destination 集合 | O(1) |
SDIFF key [key …] | 返回第一個集合與其他集合之間的差異(差集) | O(N),其中 N 為所有集合中成員的總數量 |
SDIFFSTORE destination key [key …] | 返回給定所有集合的差集并存儲在 destination 中 | O(N),其中 N 為所有集合中成員的總數量 |
SINTER key [key …] | 返回所有給定集合的交集 | O(N*M),其中 N 為最小集合中元素的數量,M 為參數中集合的數量 |
SINTERSTORE destination key [key …] | 返回所有給定集合的交集并存儲在 destination 中 | O(N*M),其中 N 為最小集合中元素的數量,M 為參數中集合的數量 |
SUNION key [key …] | 返回所有給定集合的并集 | O(N),其中 N 為所有集合中成員的總數量 |
SUNIONSTORE destination key [key …] | 返回所有給定集合的并集并存儲在 destination 中 | O(N),其中 N 為所有集合中成員的總數量 |
SSCAN key cursor [MATCH pattern] [COUNT count] | 迭代集合中的元素 | O(1)(每次調用),完整迭代為 O(N) |
Zset 有序集合
有序集合保留了集合不能有重復成員的特點,但與集合不同的是,有序集合中的每個元素都有一個唯一的浮點類型的分數(score)與之關聯,這使得有序集合中的元素是可以維護有序性的,但這個有序不是用下標作為排序依據而是用這個分數。
有序集合中的元素是不能重復的,但分數允許重復。類比于一次考試之后,每個人一定有一個唯一的分數,但分數允許相同。
ZADD 命令
添加或者更新指定的元素以及關聯的分數到 zset 中,分數應該符合 double 類型,+inf/-inf 作為正負極限也是合法的。
ZADD 的相關選項:
- XX:僅僅用于更新已經存在的元素,不會添加新元素。
- NX:僅用于添加新元素,不會更新已經存在的元素。
- CH:默認情況下,ZADD 返回的是本次添加的元素個數,但指定這個選項之后,就會還包含本次更新的元素的個數。
- INCR:此時命令類似 ZINCRBY 的效果,將元素的分數加上指定的分數。此時只能指定一個元素和分數。
基本命令表
命令 | 描述 | 時間復雜度 |
---|---|---|
ZADD key score member [score member …] | 添加一個或多個成員到有序集合,或者更新已存在成員的分數。 | O(k * log(n)),其中 k 是添加的成員個數,n 是當前有序集合的元素個數。 |
ZCARD key | 獲取有序集合的成員數。 | O(1) |
ZSCORE key member | 返回有序集中,成員的分數值。 | O(1) |
ZRANK key member | 返回有序集中指定成員的排名(從 0 開始,按分數升序)。 | O(log(n)),其中 n 是當前有序集合的元素個數。 |
ZREVRANK key member | 返回有序集中指定成員的排名(從 0 開始,按分數降序)。 | O(log(n)),其中 n 是當前有序集合的元素個數。 |
ZREM key member [member …] | 移除有序集合中的一個或多個成員。 | O(k * log(n)),其中 k 是刪除的成員個數,n 是當前有序集合的元素個數。 |
ZINCRBY key increment member | 為有序集中成員的分數加上增量 increment。 | O(log(n)),其中 n 是當前有序集合的元素個數。 |
ZRANGE key start end [WITHSCORES] | 返回有序集中指定區間內的成員,按分數從低到高排序。 | O(k + log(n)),其中 k 是獲取的成員個數,n 是當前有序集合的元素個數。 |
ZREVRANGE key start end [WITHSCORES] | 返回有序集中指定區間內的成員,按分數從高到低排序。 | O(k + log(n)),其中 k 是獲取的成員個數,n 是當前有序集合的元素個數。 |
ZRANGEBYSCORE key min max [WITHSCORES] | 返回所有成員的分數在 [min, max] 范圍內的成員,按分數從低到高排序。 | O(k + log(n)),其中 k 是獲取的成員個數,n 是當前有序集合的元素個數。 |
ZREVRANGEBYSCORE key max min [WITHSCORES] | 返回所有成員的分數在 [max, min] 范圍內的成員,按分數從高到低排序。 | O(k + log(n)),其中 k 是獲取的成員個數,n 是當前有序集合的元素個數。 |
ZCOUNT key min max | 計算分數在 [min, max] 范圍內的成員數量。 | O(log(n)),其中 n 是當前有序集合的元素個數。 |
ZREMRANGEBYRANK key start end | 移除有序集合中給定的排名區間的所有成員。 | O(k + log(n)),其中 k 是移除的成員個數,n 是當前有序集合的元素個數。 |
ZREMRANGEBYSCORE key min max | 移除有序集合中所有分數在 [min, max] 范圍內的成員。 | O(k + log(n)),其中 k 是移除的成員個數,n 是當前有序集合的元素個數。 |
ZINTERSTORE destination numkeys key [key …] | 計算給定的一個或多個有序集的交集,并將結果存儲在新的有序集合中。 | O(n * k) + O(m * log(m)),其中 n 是輸入集合中的最小元素個數,k 是集合個數,m 是目標集合元素個數。 |
ZUNIONSTORE destination numkeys key [key …] | 計算給定的一個或多個有序集的并集,并將結果存儲在新的有序集合中。 | O(n) + O(m * log(m)),其中 n 是輸入集合的總元素個數,m 是目標集合元素個數。 |