wordpress 博客 簡(jiǎn)書(shū)有必要買(mǎi)優(yōu)化大師會(huì)員嗎
介紹
Hash 類(lèi)型特別適合存儲(chǔ)對(duì)象,例如用戶(hù)信息等。
String類(lèi)型也可以用于存儲(chǔ)用戶(hù)信息,Hash與String存儲(chǔ)用戶(hù)信息的區(qū)別如下圖所示:
內(nèi)部實(shí)現(xiàn)
Hash 類(lèi)型 的底層數(shù)據(jù)結(jié)構(gòu)是通過(guò)壓縮列表(Ziplist)或哈希表(Hash Table)實(shí)現(xiàn)的:
-
如果 Hash 類(lèi)型的元素個(gè)數(shù)小于 512(默認(rèn)值,可通過(guò)配置 hash-max-ziplist-entries 調(diào)整),并且所有值都小于 64 字節(jié)(默認(rèn)值,可通過(guò)配置 hash-max-ziplist-value 調(diào)整),Redis 會(huì)使用壓縮列表作為底層數(shù)據(jù)結(jié)構(gòu)。
-
如果Hash類(lèi)型的元素不滿(mǎn)足上述條件,那么Redis將會(huì)使用哈希表作為Hash類(lèi)型的底層數(shù)據(jù)結(jié)構(gòu)。
在 Redis 7.0 版本中,壓縮列表數(shù)據(jù)結(jié)構(gòu)已經(jīng)被廢棄,取而代之的是 Listpack 數(shù)據(jù)結(jié)構(gòu)。Listpack 是一種新的壓縮數(shù)據(jù)結(jié)構(gòu),其目的是提供更好的性能和更高的存儲(chǔ)效率。
常用命令
插入單個(gè)元素。
hset key field value#示例
> hset myhash k1 v11
> hset myhash k2 v21
查詢(xún)單個(gè)元素。
hget key field#示例
> hget myhash k2
“v2”
當(dāng)某個(gè)key不存在時(shí),插入數(shù)據(jù)。
hsetnx key field value#示例
> hsetnx myhash k3 v3
(integer) 1
> hget myhash k3
"v3"
如果嘗試插入一個(gè)已存在的鍵,則原始值將不會(huì)改變,如下例所示:
> hsetnx myhash k3 val3
(integer) 0
> hget myhash k3
"v3"
刪除鍵中的一個(gè)或多個(gè)元素。
hdel myhash field [field …]#示例
> hdel myhash k1 v1
(integer) 1
注意:hdel 命令只用于從哈希表中刪除一個(gè)或多個(gè)特定的字段,但它不會(huì)刪除整個(gè)key。如果你想刪除整個(gè)哈希表,你應(yīng)該使用 del 命令。
累加某個(gè)整數(shù)類(lèi)型的字段值。
hincrby key field increment#示例
> hset myhash k4 4
1
> hincrby myhash k4 2
(integer) 6
> hget myhash k4
"6"
更多操作命令,詳見(jiàn)文章末尾。
應(yīng)用場(chǎng)景
購(gòu)物車(chē)
以用戶(hù)id為key,以商品sku id為field,以商品數(shù)量為value剛好構(gòu)成了購(gòu)物車(chē)的三個(gè)要素,如下圖所示。
涉及的命令如下:
#將商品添加到購(gòu)物車(chē)中,{user_id} 是用戶(hù)的ID,{sku_id} 是商品的SKU ID,1 是初始數(shù)量。
HSET cart:{user_id} {sku_id} 1# 增加購(gòu)物車(chē)中某個(gè)商品的數(shù)量
HINCRBY cart:{user_id} {sku_id} 1# 統(tǒng)計(jì)購(gòu)物車(chē)中商品的總數(shù)量,即購(gòu)物車(chē)中包含多少個(gè)不同的商品。
HLEN cart:{user_id}# 刪除商品
HDEL cart:{user_id} {sku_id}# 獲取購(gòu)物車(chē)中所有商品信息
HGETALL cart:{user_d}
然而,需要注意的是,這里Redis僅保存了商品SKU ID和數(shù)量,而商品的完整信息(如名稱(chēng)、價(jià)格、描述等)需要通過(guò)商品ID去數(shù)據(jù)庫(kù)中查詢(xún),以便展示完整的商品信息。
緩存對(duì)象
Hash 類(lèi)型的 (key, field, value) 結(jié)構(gòu)與對(duì)象的 (objectid, attribute, value) 結(jié)構(gòu)類(lèi)似,因此也可以用于存儲(chǔ)對(duì)象。
我們以用戶(hù)信息為例,其在關(guān)系數(shù)據(jù)庫(kù)中的結(jié)構(gòu)是這樣的:
我們可以使用下面的命令將用戶(hù)對(duì)象的信息存儲(chǔ)到Hash類(lèi)型中:
> HMSET uid:1 name Jerry age 20
OK> HMSET uid:2 name Tom age 20
OK> HGETALL uid:1
1) "name"
2) "Jerry"
3) "age"
4) "20"
在介紹String類(lèi)型的應(yīng)用場(chǎng)景的時(shí)候已經(jīng)介紹過(guò)了,String+Json也是一種存儲(chǔ)對(duì)象的方式,那么在存儲(chǔ)對(duì)象的時(shí)候,到底應(yīng)該用String+json還是Hash呢?
String + JSON:這種方式將整個(gè)對(duì)象序列化為一個(gè) JSON 字符串,存儲(chǔ)在 Redis 的 String 類(lèi)型中。這種方法適用于對(duì)象結(jié)構(gòu)復(fù)雜且整體更新較少的情況。
Hash:這種方式將對(duì)象的每個(gè)屬性存儲(chǔ)為 Hash 類(lèi)型的字段值對(duì)。這種方法適用于對(duì)象中一些屬性頻繁變化的情況。
更多hash操作命令
1. 查詢(xún)一個(gè)或多個(gè)字段值。
hmget key field [field …]> hmget uid:1 name age
1) "Jerry"
2) "20"
2. 查詢(xún)某個(gè)key的所有字段。
hkeys key> hkeys uid:1
1) "name"
2) "age"
3. 查詢(xún)某個(gè)鍵的所有字段值。
hvals key> hvals uid:1
1) "Jerry"
2) "20"
4. 對(duì)某個(gè)浮點(diǎn)型字段進(jìn)行累加。
hincrbyfloat key field increment> hset floathash k1 1.2
1
> hincrbyfloat floathash k1 2.2
3.4
5. 查詢(xún)某個(gè)字段是否存在。
hexists key field> hexists floathash k1
(integer) 1