1. 哈希(hash)
哈希類型是指 redis 鍵值對中的值本身又是一個鍵值對結構,形如 value=[{field1,value1},...{fieldN,valueN}],其與 redis 字符串對象的區別
2. 內部實現
哈希類型的內部編碼有兩種:ziplist (壓縮列表), hashtable (哈希表)。只有當存儲的數據量比較小的情況下,redis 才使用壓縮列表來實現字典類型。具體需要滿足兩個條件:
-
當哈希類型元素個數小於 hash-max-ziplist-entries 配置(默認512個)
-
所有值都小於 hash-max-ziplist-value 配置(默認64字節)
ziplist 使用更加緊湊的結構實現多個元素的連續存儲,所以在節省內存方面比 hashtable 更加優秀。當哈希類型無法滿足 ziplist 的條件時,redis 會使用 hashtable 作為哈希的內部實現,因為此時 ziplist 的讀寫效率會下降,而 hashtable 的讀寫時間復雜度為O(1)。
2. 常用命令
命令 | 描述 |
---|---|
hdel key field1 [field2] | 刪除一個或多個字段 |
hexists key field | 查看字段是否存在 |
hget key field | 獲取指定字段 |
hgetall key | 獲取所有字段 |
hincrby key field increment | 字段值加上指定增量值 |
hincrbyfloat key field increment | 浮點值加上指定增量值 |
hkeys key | 獲取所有哈希表中的字段 |
hlen key | 獲取哈希表中字段的數量 |
hmget key field1 [field2] | 獲取所有給定字段的值 |
hmset key field1 value1 [field2 value2 ] | 同時將多個 field-value (域-值)對設置到哈希表 key 中 |
hset key field value | 將哈希表 key 中的字段 field 的值設為 value |
hsetnx key field value | 設置hash的一個字段,只有當這個字段不存在時有效 |
hvals key | 獲取hash中所有值 |
hscan key cursor [MATCH pattern] [COUNT count] | 迭代hash中的元素 |
3. 使用場景
-
存儲對象
如存儲一些對象信息,如用戶信息、商品信息、配置信息等
如用戶信息它在關系型數據庫中的結構是這樣的
id 1 name age 1 tom 15 2 jerry 13 而使用 redis Hash 存儲其結構如下圖:
-
購物車
很多電商網站都會使用 cookie實現購物車,優點就是:無須對數據庫進行寫入,而缺點是:程序需要重新解析和驗證 cookie,數據多了之后請求發送和處理的速度可能會有所降低。
購物車的定義非常簡單:我們以每個用戶的用戶 id 作為 redis 的 key,每個用戶的購物車都是一個哈希表,這個哈希表存儲了商品 id 與商品訂購數量之間的映射。在商品的訂購數量出現變化時,操作 redis 哈希對購物車進行更新
-
計數器
redis 哈希表作為計數器的使用也非常廣泛。它常常被用在記錄網站每一天、一月、一年的訪問數量。每一次訪問,我們在對應的 field 上自增1
4. 遇到問題
-
在用 redis 存儲已經排序好的數據,獲取時會出現無序
可以使用函數進行排序處理
// 二維數組按照 score 和 time 進行排序
array_multisort(array_column($array, 'score'), SORT_DESC, array_column($array, 'time'), SORT_DESC, $array);