共計(jì) 2616 個(gè)字符,預(yù)計(jì)需要花費(fèi) 7 分鐘才能閱讀完成。
這篇文章主要介紹 redis 中的 hash 數(shù)據(jù)類型怎么用,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
1. hash 類型數(shù)據(jù)概述
我們先來(lái)看這個(gè)例子
在上一節(jié)我們一起了解了 string 存儲(chǔ)類型。但是如果是對(duì)象數(shù)據(jù)的存儲(chǔ)具有較頻繁的更新需求,操作會(huì)顯得笨重。例如:user:id:100 – {id :100, name : 春晚 , fans :12355, blogs :99, focus:83},如果需要更新一個(gè)對(duì)象中的局部數(shù)據(jù),就需要替換掉所有數(shù)據(jù),于是有了以下的需求。
新的需求:對(duì)一系列存儲(chǔ)的數(shù)據(jù)進(jìn)行編組,方便管理,比如存儲(chǔ)一個(gè)對(duì)象的信息需要的存儲(chǔ)結(jié)構(gòu):一個(gè)存儲(chǔ)空間保存多個(gè)鍵值對(duì)數(shù)據(jù)
如下圖:
為了解決這個(gè)問(wèn)題,我們引入新的數(shù)據(jù)類型:hash。同時(shí) hash 存儲(chǔ)結(jié)構(gòu)也做了以下優(yōu)化
如果 field 數(shù)量較小,存儲(chǔ)結(jié)構(gòu)優(yōu)化為類數(shù)組結(jié)構(gòu)
如果 field 數(shù)量較多,存儲(chǔ)結(jié)構(gòu)使用 HashMap 結(jié)構(gòu)
2. hash 類型數(shù)據(jù)的基本操作
修改 / 添加數(shù)據(jù)
hset key field value
查詢單個(gè)字段 / 查詢所有字段
# 查詢單個(gè)字段數(shù)據(jù)
hget key field
# 查詢所有數(shù)據(jù)
hgetall key
刪除操作
hdel key field1 [field2]
修改 / 添加多個(gè)數(shù)據(jù)
hmset key field1 value1 field2 value2
返回 hash 表中,一個(gè)或多個(gè)給定字段的值
hmget key field1 field2
獲取 hash 表中字段的數(shù)量
hlen key
獲取 hash 表中是否存在指定的字段
hexists key field
3. hash 類型數(shù)據(jù)的擴(kuò)展操作
獲取 hash 表中所有字段名或字段值
hkey key
hvals key
設(shè)置指定字符段的數(shù)值數(shù)據(jù)增加指定范圍的值
hincrby key field increment
hincrbyfloat key field increment
hash 類型數(shù)據(jù)操作注意事項(xiàng)
hash 類型下的 value 只能存儲(chǔ)字符串,不允許存儲(chǔ)其他數(shù)據(jù)類型,不存在嵌套對(duì)象。如果數(shù)據(jù)未獲取到,對(duì)應(yīng)的結(jié)果為 (nil);
每個(gè) hash 可以存儲(chǔ) 2 的 32 次方減 1 個(gè)鍵值對(duì);
hash 類型十分貼近對(duì)象的數(shù)據(jù)存儲(chǔ)形式,并且可以靈活添加刪除對(duì)象屬性,但 hash 設(shè)計(jì)初衷不是為了存儲(chǔ)大量對(duì)象而設(shè)計(jì),切記不可濫用,更不可以將 hash 作為對(duì)象列表使用;
hgetall 操作可以獲取全部屬性,如果內(nèi)部 field 過(guò)多,遍歷整個(gè)數(shù)據(jù)效率會(huì)很低,有可能成為數(shù)據(jù)訪問(wèn)瓶頸。
4. hash 的應(yīng)用案例 4.1. 用 hash 實(shí)現(xiàn)購(gòu)物車
概述
在這里我們不討論購(gòu)物車與數(shù)據(jù)庫(kù)間的持久化同步,也不討論購(gòu)物車與訂單之間的關(guān)系,同時(shí)忽略未登錄用戶購(gòu)物車信息存儲(chǔ)。我們僅僅用 redis 的存儲(chǔ)模型來(lái) 對(duì)購(gòu)物車 的條目進(jìn)行 添加、瀏覽、更改數(shù)量、刪除、清空
實(shí)現(xiàn)方案
以客戶 id 作為 key,每位用戶創(chuàng)建一個(gè) hash 存儲(chǔ)結(jié)構(gòu)對(duì)應(yīng)購(gòu)物車信息
將商品編號(hào)作為 field,購(gòu)買數(shù)量作為 value 進(jìn)行存儲(chǔ)
添加商品:追加全新的 field 與 value
瀏覽商品:遍歷 hash
更改數(shù)量:自增 / 自減,設(shè)置 value 值
刪除商品:刪除 field
清空:刪除 key
示例代碼如下:
# 001 用戶購(gòu)買 ID 為 101 商品 100 件,ID 為 102 的商品 200 件
hmset 001 101 100 102 200
# 002 用戶購(gòu)買 ID 為 102 商品 1 件,ID 為 104 的商品 7 件
hmset 002 102 1 104 7
商品信息加速
當(dāng)前僅僅是將數(shù)量存儲(chǔ)到 redis 中,并沒(méi)有起到加速作用,因?yàn)樯唐沸畔⑦€需要查詢數(shù)據(jù)庫(kù)。可以使用以下方案解決:
每條購(gòu)物車中的商品信息記錄保存為兩個(gè) field
field1 專門用于保存數(shù)量
命名格式:商品 id:nums
保存數(shù)據(jù):數(shù)值
field2 專門用于保存購(gòu)物車中顯示的商品信息,包含文字描述,圖片地址,所屬商家信息等
命名格式:商品 id:info
保存數(shù)據(jù):json
示例代碼如下:
# 001 用戶 購(gòu)買 ID 為 101 的商品 2 件,商品的信息為:{name : good name}
hmset 001 101:num 2 101:info {\ name\ :\ goods name\}
# 002 用戶 購(gòu)買 ID 為 101 的商品 1 件,商品的信息為:{name : good name}
hmset 002 101:num 1 101:info {\ name\ :\ goods name\}
在上面的 101:info 對(duì)應(yīng)的值中,字符串包含了空格,所以用雙引號(hào)引用起來(lái),達(dá)到轉(zhuǎn)義的目的。
商品信息獨(dú)立保存
由于 field2 可能在多條商品記錄中存在,因此 field2 里的數(shù)據(jù)可保存到獨(dú)立的 hash。此時(shí),如果每添加一條購(gòu)物車記錄,就保存一次 hash 數(shù)據(jù),顯然是不合理的,可以通過(guò) hsetnx 操作來(lái)保存數(shù)據(jù),如果數(shù)據(jù)存在,則不執(zhí)行保存操作。
命令格式如下
hsetnx key field value
代碼示例如下
# 將 id 為 101 的商品獨(dú)立存起來(lái)
hsetnx info 101 {\ name\ :\ goods name\}
4.1. 用 hash 實(shí)現(xiàn)搶購(gòu)
案例:雙 11 活動(dòng)日,銷售手機(jī)充值卡的商家對(duì)移動(dòng)、聯(lián)通、電信的 30 元、50 元、100 元商品推出搶購(gòu)活動(dòng),每種商品的搶購(gòu)上限為 100。
解決方案
以商家 id 作為 key
將參與搶購(gòu)的商品作為 field
將參與搶購(gòu)的商品數(shù)量作為對(duì)應(yīng)的 value
搶購(gòu)時(shí)使用降值的方式控制產(chǎn)品數(shù)量
實(shí)際業(yè)務(wù)中還有超賣等實(shí)際問(wèn)題,這里不做討論
實(shí)現(xiàn)過(guò)程
商品初始信息
# p01 商家下,c30 充值券 1000 張,c50 充值券 1000 張,c100 充值券 1000 張
hmset p01 c30 1000 c50 1000 c100 1000
當(dāng) c30 售出 1 件時(shí),值減 1;當(dāng) c100 售出 20 件時(shí),值減 20,如下代碼
# p01 商家,商品 c30 售出 1 件
hincrby p01 c30 -1
# p01 商家,商品 c100 售出 20 件
hincrby p01 c100 -20
5. string 存對(duì)象對(duì)比 hash 存對(duì)象
string 存儲(chǔ) json 字符串:讀取方便,在更新的時(shí)候會(huì)整體進(jìn)行更新
hash 存對(duì)象具體的字段:更新靈活
引入 hash 數(shù)據(jù)類型之后,我們就解決了 string 存儲(chǔ)對(duì)象,更新對(duì)象時(shí)需要整體更新的問(wèn)題。
以上是“redis 中的 hash 數(shù)據(jù)類型怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道!