Redis 數據結構

  • 2021 年 6 月 17 日
  • 筆記

Redis 可以理解為一個大號的 Map,其中所有的數據都採用 key:value 的形式維護,在 Redis 中,一個 key 總是對應一個 value。其中 key 永遠是字符串,而一般提到 Redis 的數據類型,指的是其存儲的 value 的數據類型。下面介紹 Redis 常見的數據類型,並簡單介紹常見的相關指令。

string

string 是最基本的數據類型,其他幾個數據類型底層也是通過 string 來實現的。

flowchart LR
subgraph values
value-one
value-two
end
subgraph keys
key:one –> value-one
key:two –> value-two
end

string 有以下幾個特點:

  • string 類型用 nil 表示不存在的值,類似於編程語言中的 null。
  • string 類型可存儲的最大長度為 512M。
  • Redis 中沒有專門的數字類型,當一個 string 中存放的數據全部為數字、且該數字的範圍在 64位長整型範圍中時,Redis 可以將其當作數字進行操作。

基本操作

  • 添加/修改數據:set key value,當 key 已存在時會更新其對應的值,返回 OK 表示執行成功,其他很多命令執行成功時也會返回 OK,不再贅述。
  • 獲取數據:get key,當 key 不存在時返回 nil。
  • 添加/修改一個或多個數據:mset key value [key value ...][key value ...] 表示該命令的參數可以是任意數量的 key、value 對,這種寫法與 Redis 官方文檔相同,本文也多次使用這種方式。
  • 獲取一個或多個數據:mget key [key ...],返回的順序與參數指定的順序相同,如果參數中傳入了不存在的 key,返回結果中對應位置也會有一個 nil。
  • 刪除一個或多個:del key [key ...],與 MySQL 類似,返回結果是一個 Integer,表示改動的記錄數量,其他很多命令執行成功也會返回 OK,不再贅述。
  • 獲取字符串長度:strlen key
  • 追加信息到原數據後:append key value,追加完成後返回新的字符串長度。

拓展操作

數字的自增自減

  • 自增一 incr key,如果 key 對應的值不是純數字字符串、或自增後會超過64位長整型範圍,該指令會報錯。
  • 自增指定的整數 incrby key increment,increment 自增係數如果是負數也可以實現自減的操作。
  • 自增指定的浮點數 incrbyfloat key increment
  • 自減一 decr key
  • 自減指定的整數 decrby key decrement
  • 沒有自減指定的浮點數命令

hash

哈希表 hash 用於分組存儲數據,可類比編程語言中的哈希數據結構,一個 key 對應一整個哈希表,哈希表中可以有多個字段 field 和字段的對應值 value,字段名和字段值都是字符串,受 string 類型特點的約束。

flowchart LR
subgraph values
subgraph hash
field-one –> value-one
field-two –> value-two
end
end
subgraph keys
subgraph key
end
end
key –> hash

哈希結構有以下幾個特點:

  • 在一個哈希表中,字段不可重複,字段值可以重複。
  • 仍保有哈希表的普遍特點,例如查詢效率高等。
  • 每個哈希表可以存儲 232 – 1個鍵值對。

基本操作

  • 添加/修改哈希表中字段和對應的值:hset key field value [field value ...]。此外還有功能類似的 hmset 命令,在 Redis 官方文檔中被標記為已廢棄。
  • 獲取哈希表中某個字段的值:hget key field
  • 獲取哈希表中所有字段的值:hgetall key
  • 獲取哈希表中某些字段的值:hmget key field [feild ...]
  • 獲取哈希表中字段的數量:hlen key
  • 檢查哈希表中是否存在指定的字段:hexists key field
  • 刪除哈希表中某些數據:hdel key field [field ...]

擴展操作

獨有操作

  • 獲取一個哈希表中所有字段名:hkeys key
  • 獲取一個哈希表中所有字段值:hvals key

數字的自增自減

  • 將一個哈希表中某個字段的值自增指定的整數:hincrby key field increment,與前面出現的自增指令相同,increment 為負值時可以實現自減的功能。
  • 將一個哈希表中某個字段的值自增指定的浮點數:hincrbyfloat key field increment

list

列表 list 用於區分數據進出的順序,類似與編程語言中的雙端隊列,一個 key 對應一個列表,列表中存放的是元素 element,每個元素都是由 string 構成的,受 string 類型特點的約束。通過專門的、僅使用一部分命令可分別實現棧或隊列。

flowchart LR
subgraph values
subgraph element
elementone[[elementone]]
elementtwo[[elementtwo]]
elementthree[[elementthree]]
elementone<–>elementtwo<–>elementthree
end
end
subgraph keys
subgraph key
end
end
key–>element
  • 列表中最多可以存儲 232 – 1個元素。
  • 列表的相關命令較多,因為 Redis 為很多操作都提供了從左側和右側獲取兩種方式,分別以 l 和 r 開頭。
  • 列表的元素可通過索引獲取,索引編號從 0 開始,-1 表示倒數第一個元素。後續命令中,index、start 和 stop 指索引的範圍。

基本操作

  • 添加元素到列表中:左側添加lpush key element [element ...] 和右側添加 rpush ley element [element ...]由於列表結構的特殊性,這兩條命令不能通過覆蓋原始值的方式實現修改的功能
  • 獲取列表中指定位置的元素:lindex key index,這條命令沒有對應的 rindex 命令,可以理解為此處的 l 是 list 的縮寫,而不是 left,下面兩條同理。
  • 獲取列表的長度:llen key
  • 獲取列表指定範圍內的元素:lrange key start stop
  • 獲取並移除列表中的元素:lpop keyrpop key

拓展操作

  • 從列表左側開始,刪除指定的元素,刪除一定數量後停止:lrem key count element 。假如列表 mylist 中有幾個元素如下:a b c a b c a b c,執行命令 lrem mylist 2 b 後,隊列中剩下的元素是 a c a c a b c

set

集合 set 與哈希結構類似,一個 key 對應一個集合,集合中存放的是成員 member,成員都是由 string 組成的,受 string 類型特點的約束。其底層實現方式就是在哈希的字段名上存放數據、而所有的字段值都是 nil。

flowchart LR
subgraph values
subgraph set
member-one
member-two
end
end
subgraph keys
subgraph key
end
end
member-one –> nil
member-two –> nil
key –> set

集合結構有以下幾個特點:

  • 仍保有 set 集合的普遍特點,例如不能存放重複值,高效的查詢等。
  • 每個集合可以存儲 232 – 1個值對。

基本操作

  • 添加成員:sdd key member [member ...] ,當指定成員存在時,既不必更新也不會報錯。
  • 獲取全部成員:smembers key
  • 刪除數據:srem key member [member ...]

拓展操作

獨有操作

  • 獲取集合成員總數:scard key
  • 判斷集合中是否包含指定成員:sismember key member,返回 1 表示存在、返回 0 表示不存在。

隨機獲取

  • 隨機獲取集合中指定數量的成員:srandmember key [count]
  • 隨機獲取集合中指定數量的成員並移出集合:spop key [count]

集合運算

  • 求交集並返回結果:sinter key [key ...]
  • 求並集並返回結果:sunion key [key ...]
  • 求差集並返回結果:sdiff key [key ...]
  • 求交集並保存結果到目標集合:sinterstore destination key [key ...],destination 是目標集合的 key。
  • 求並集並保存結果到目標集合:sunionstore destination key [key ...]
  • 求差集並保存結果到目標集合:sdiffstore destination key [key ...]
  • 將原集合中某個數據轉移到目標集合中:smove source destination member

sorted_set

有序集合 sorted_set (也縮寫為 zset)是在 set 的基礎上,又增加了用於排序的分數 score。

flowchart LR
subgraph values
subgraph set
score-one
score-two
member-one
member-two
end
end
subgraph keys
subgraph key
end
end
score-one — member-one –> nil
score-two — member-two –> nil
key –> set

基礎操作

  • 添加/修改成員和對應的分數:zadd key score member [score member ...],當 member 已存在時,這條指令可以用於更新分數。
  • 獲取集合的成員總數:zcard key
  • 獲取集合中指定成員對應的分數:score key member
  • 刪除集合中指定的成員:zrem key member [member ...]

根據索引操作

  • 獲取指定索引範圍內的成員,按分數升序排列:zrange key start stop [WITHSORES],如果入參有 withscores 返回結果也會帶上成員對應的分數。
  • 獲取指定索引範圍內的成員,按分數降序排列:zrevrange key start stop [WITHSORES]
  • 按索引刪除數據:zremrangebyrank key start stop

根據分數操作

  • 獲取指定分數範圍內的成員,按分數升序排列:zrangebyscore key min max [WITHSCORES] [LIMIT offset count]。操作分數時,默認是閉區間,可加上符號 ( 表示開區間。[LIMIT offset count] 是偏移量和計數的限制。
  • 獲取指定分數範圍內的成員,按分數降序排列:zrevrangebyscore key min max [WITHSCORES] [LIMIT offset count]
  • 按分數刪除數據:zremrangebyscore key min max
  • 計算某個分數範圍內成員總數:zcount key min max
  • 返回集合中指定成員按分數升序排列後的排名:zrank key member
  • 返回集合中指定成員按分數降序排列後的排名:zrevrank key member

拓展操作

數字的自增自減

  • 將集合中指定成員的數據自增:zincrby key increment member

集合運算

  • 交集:zinterstore destination numkeys key [key ...]
  • 並集:zunionstore destination numkeys key [key ...]