首頁 >資料庫 >Redis >聊聊redis中的hash資料類型,如何操作?

聊聊redis中的hash資料類型,如何操作?

青灯夜游
青灯夜游轉載
2021-12-31 10:16:252594瀏覽

這篇文章帶大家了解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中的hash資料類型,如何操作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除