聊聊redis中的hash數據類型,如何操作?

本篇文章帶大家了解一下redis中的hash數據類型,介紹一下hash 類型數據的基本操作,希望對大家有所幫助!

聊聊redis中的hash數據類型,如何操作?

1. hash類型數據概述

我們先來看這個例子

在上一節我們一起了解了 string 存儲類型。但是如果是對象數據的存儲具有較頻繁的更新需求,操作會顯得笨重。例如:user:id:100 -> {“id”:100,”name”:”春晚”,”fans”:12355,”blogs”:99,”focus:83},如果需要更新一個對象中的局部數據,就需要替換掉所有數據,于是有了以下的需求。【相關推薦:Redis視頻教程

新的需求:對一系列存儲的數據進行編組,方便管理,比如存儲一個對象的信息需要的存儲結構:一個存儲空間保存多個鍵值對數據

如下圖:

聊聊redis中的hash數據類型,如何操作?

為了解決這個問題,我們引入新的數據類型:hash。同時 hash 存儲結構也做了以下優化

  • 如果 field 數量較小,存儲結構優化為類數組結構
  • 如果 field 數量較多,存儲結構使用 HashMap 結構

2. hash 類型數據的基本操作

  • 修改/添加數據
hset?key?field?value
  • 查詢單個字段/查詢所有字段
#?查詢單個字段數據 hget?key?field #?查詢所有數據 hgetall?key
  • 刪除操作
hdel?key?field1?[field2]
  • 修改/添加多個數據
hmset?key?field1?value1?field2?value2
  • 返回 hash 表中,一個或多個給定字段的值
hmget?key?field1?field2
  • 獲取 hash 表中字段的數量
hlen?key
  • 獲取 hash 表中是否存在指定的字段
hexists?key?field

3. hash 類型數據的擴展操作

  • 獲取 hash 表中所有字段名或字段值
hkey?key hvals?key
  • 設置指定字符段的數值數據增加指定范圍的值
hincrby?key?field?increment hincrbyfloat?key?field?increment

hash 類型數據操作注意事項

  • hash 類型下的 value 只能存儲字符串,不允許存儲其他數據類型,不存在嵌套對象。如果數據未獲取到,對應的結果為(nil);

  • 每個 hash 可以存儲 2 的 32 次方減 1 個鍵值對;

  • hash 類型十分貼近對象的數據存儲形式,并且可以靈活添加刪除對象屬性,但 hash 設計初衷不是為了存儲大量對象而設計,切記不可濫用,更不可以將 hash 作為對象列表使用;

  • hgetall 操作可以獲取全部屬性,如果內部 field 過多,遍歷整個數據效率會很低,有可能成為數據訪問瓶頸。

4. hash的應用案例

4.1. 用hash實現購物車

概述

在這里我們不討論購物車與數據庫間的持久化同步,也不討論購物車與訂單之間的關系,同時忽略未登錄用戶購物車信息存儲。我們僅僅用 redis 的存儲模型來 對購物車 的條目進行 添加、瀏覽、更改數量、刪除、清空

實現方案

  • 以客戶 id 作為 key,每位用戶創建一個 hash 存儲結構對應購物車信息
  • 將商品編號作為 field,購買數量作為 value 進行存儲
  • 添加商品:追加全新的 field 與 value
  • 瀏覽商品:遍歷 hash
  • 更改數量:自增/自減,設置 value 值
  • 刪除商品:刪除 field
  • 清空:刪除 key

示例代碼如下:

#?001?用戶購買?ID為101商品?100件,ID為102的商品?200件 hmset?001?101?100?102?200 #?002?用戶購買?ID為102商品?1件,ID為104的商品?7件 hmset?002?102?1?104?7

商品信息加速

當前僅僅是將數量存儲到 redis 中,并沒有起到加速作用,因為商品信息還需要查詢數據庫。可以使用以下方案解決:

每條購物車中的商品信息記錄保存為兩個 field

  • field1 專門用于保存數量

命名格式:商品 id:nums 保存數據:數值

  • field2 專門用于保存購物車中顯示的商品信息,包含文字描述,圖片地址,所屬商家信息等

命名格式:商品 id:info 保存數據:json

示例代碼如下:

#?001?用戶?購買?ID為101的商品?2件,商品的信息為:{"name":"good?name"}? hmset?001?101:num?2??101:info?"{"name":"goods?name"}" #?002?用戶?購買?ID為101的商品?1件,商品的信息為:{"name":"good?name"}? hmset?002?101:num?1??101:info?"{"name":"goods?name"}"

在上面的101:info 對應的值中,字符串包含了空格,所以用雙引號引用起來,達到轉義的目的。

商品信息獨立保存

由于 field2 可能在多條商品記錄中存在,因此 field2 里的數據可保存到獨立的 hash。此時,如果每添加一條購物車記錄,就保存一次 hash 數據,顯然是不合理的,可以通過hsetnx操作來保存數據,如果數據存在,則不執行保存操作。

命令格式如下

hsetnx?key?field?value

代碼示例如下

#?將id為101?的商品獨立存起來 hsetnx?info?101?"{"name":"goods?name"}"

4.1. 用hash實現搶購

案例:雙 11 活動日,銷售手機充值卡的商家對移動、聯通、電信的 30 元、50 元、100 元商品推出搶購活動,每種商品的搶購上限為 100。

解決方案

  • 以商家 id 作為 key
  • 將參與搶購的商品作為 field
  • 將參與搶購的商品數量作為對應的 value
  • 搶購時使用降值的方式控制產品數量
  • 實際業務中還有超賣等實際問題,這里不做討論

實現過程

商品初始信息

#?p01商家下,c30充值券1000張,c50充值券1000張,c100充值券1000張 hmset?p01?c30?1000?c50?1000?c100?1000

當 c30 售出1件時,值減 1; 當 c100 售出 20 件時,值減 20,如下代碼

#?p01商家,商品c30售出1件 hincrby?p01?c30?-1 #?p01商家,商品c100售出20件 hincrby?p01?c100?-20

5. string 存對象對比 hash 存對象

  • string 存儲 json 字符串:讀取方便,在更新的時候會整體進行更新

  • hash 存對象具體的字段:更新靈活

引入 hash 數據類型之后,我們就解決了 string 存儲對象,更新對象時需要整體更新的問題。

更多編程相關知識,請訪問:Redis視頻教程!!

以上就是聊聊

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享