redis系列(三)—數據結構之哈希(hash)

在這裏插入圖片描述

前言

大家好,牧碼心今天給大家推薦一篇redis系列—數據結構之哈希(hash)的文章,在實際工作中有很多應用場景,希望對你有所幫助。內容如下:

  • 特點
  • 基本命令
  • 時間複雜度
  • 使用場景

特點

在Redis中, 哈希類型是指鍵值本身又是一個鍵值對結構, 形如value={{field1, value1}, …{fieldN, valueN}}, Redis鍵值對和哈希類型二者的關係可以用圖來表示:
hash結構

基本命令

  • 設置值
hset key field value

下面爲user: 1添加一對field-value:

127.0.0.1:6379> hset user:1 name tom
(integer) 1

如果設置成功會返回1, 反之會返回0。

  • 獲取值
hget key field

下面操作獲取user: 1的name域(屬性) 對應的值:

127.0.0.1:6379> hget user:1 name
"tom"

如果鍵或field不存在, 會返回nil。

  • 刪除field
hdel key field [field ...]

hdel會刪除一個或多個field, 返回結果爲成功刪除field的個數, 例如:

127.0.0.1:6379> hdel user:1 name
(integer) 1
  • 批量設置或獲取field-value
hmget key field [field ...]
hmset key field value [field value ...]

hmset和hmget分別是批量設置和獲取field-value, hmset需要的參數是key
和多對field-value, hmget需要的參數是key和多個field。 例如:

127.0.0.1:6379> hmset user:1 name mike age 12 city tianjin
OK
127.0.0.1:6379> hmget user:1 name city
1) "mike"
2) "tianjin
  • 判斷field是否存在
hexists key field

如 user:1包含name域, 所以返回結果爲1, 不包含時返回0:

127.0.0.1:6379> hexists user:1 name
(integer) 1
  • 獲取所有field
hkeys key
  • 獲取所有value
hvals key
  • 獲取所有的field-value
hgetall key

下面操作獲取user: 1所有的field-value:

127.0.0.1:6379> hgetall user:1
1) "name"
2) "mike"
3) "age"
4) "12"
5) "city"
6) "tianjin"

在使用hgetall時, 如果哈希元素個數比較多, 會存在阻塞Redis的可能。
如果開發人員只需要獲取部分field, 可以使用hmget, 如果一定要獲取全部
field-value, 可以使用hscan命令, 該命令會漸進式遍歷哈希類型。

  • 計算value的字符串長度(需要Redis3.2以上)
hstrlen key field

例如hget user:1 name的value是tom, 那麼hstrlen的返回結果是3。

127.0.0.1:6379> hstrlen user:1 name
(integer) 3

時間複雜度

下表哈希類型命令的時間複雜度,開發人員可以參考此表選擇適合的命令。
哈希類型命令的時間複雜度

使用場景

假如用關係型數據表記錄的兩條用戶信息, 用戶的屬性作爲表的列,
每條用戶信息作爲行。如圖:
關係型數據庫表保存用戶信息
用哈希類型類型存儲,如圖:
哈希類型緩存用戶信息
相比於使用字符串序列化緩存用戶信息, 哈希類型變得更加直觀, 並且在更新操作上會更加便捷。可以將每個用戶的id定義爲鍵後綴, 多對fieldvalue對應每個用戶的屬性, 類似如下僞代碼:

UserInfo getUserInfo(long id){
// 用戶id作爲key後綴
userRedisKey = "user:info:" + id;
// 使用hgetall獲取所有用戶信息映射關係
userInfoMap = redis.hgetAll(userRedisKey);
UserInfo userInfo;
if (userInfoMap != null) {
// 將映射關係轉換爲UserInfo
userInfo = transferMapToUserInfo(userInfoMap);
} else {
// 從MySQL中獲取用戶信息
userInfo = mysql.get(id);
// 將userInfo變爲映射關係使用hmset保存到Redis中
redis.hmset(userRedisKey, transferUserInfoToMap(userInfo));
// 添加過期時間
redis.expire(userRedisKey, 3600);
}r
eturn userInfo;
}

總之,使用哈希類型存儲,需要注意:
1、哈希類型是稀疏的, 而關係型數據庫是完全結構化的, 例如哈希類型
每個鍵可以有不同的field, 而關係型數據庫一旦添加新的列, 所有行都要爲
其設置值(即使爲NULL)
2、關係型數據庫可以做複雜的關係查詢, 而Redis去模擬關係型複雜查詢
開發困難, 維護成本高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章