哈希表應用
1 基本概念
鍵值關係對
"key1": {
"field1": "value1",
"field2": "value2",
"field3": "value3"
}
2 存儲原理
哈希數據結構底層有兩種實現方式
ziplist
壓縮列表hashtable
哈希表
2.1 ziplist
壓縮列表
哈希表首選的存儲方式,滿足以下條件會優先使用這個方式:
hash-max-ziplist-entries
表示的元素個數小於512(默認)- 且所有值(不是累加,也不是健,就是值)
hash-max-ziplist-value
小於64B(默認)
2.1.1 ziplist
數據結構
ziplist
數據結構是數組
<zlbytes><zltail><zllen><entry><entry>...<entry><zlend>
哈希表中的每個field,value
都是一個entry
,field
後面緊跟的就是value
。
查找過程就是遍歷數組的過程,從第一個entry
開始查找field
,然後根據field entry
中的長度header
,找到value
位置。
2.1.2 複雜度
O(N*M)
,N
是哈希表中field
的個數,M
是請求的field
個數。
數據結構是field1 value1 field2 value2
,遍歷時直接跳躍式的遍歷查找field
,因此遍歷的元素數量是field
的數量
2.2 hashtable
哈希表
- 不滿足
ziplist
的情況下,Redis自動使用哈希表
2.2.1 複雜度
O(M)
,M
是請求的field
個數
2.3 壓縮列表與哈希表對比
No | 壓縮表 | 哈希表 |
---|---|---|
數據結構 | 線性存儲方式,數組 | 鍵值對,稀疏型 |
3 哈希表應用案例
3.1 hmset/hmget
應用
設定一個key,然後將多個field-value
(字段-值)對設置到哈希表中,類似結構
{
"key1": {
"field1": "value1",
"field2": "value2",
"field3": "value3"
},
"key2": {
"field1": "value1",
"field2": "value2",
"field3": "value3"
}
}
3.1.1 hmset
特點:
- 覆蓋已經存在的字段
- 哈希表不存在,則會自動創建
- redis中的字段順序,與實際插入順序不一致
3.1.2 hmget
特點:
- 指定字段不存在,會返回
nil
- 表值的排列順序和指定字段的請求順序一樣
3.1.3 實踐案例
整體數據結構如下:
{"baidu":{"a1":"b1","a2":"b2","a3":"b3"}}
{"google":{"a1":"b1","a2":"b2","a3":"b3"}}
字典如下:
d1 = {"a1":"b1","a2":"b2","a3":"b3"}
d2 = {"a1":"b1","a2":"b2","a3":"b3"}
1. conn.hmset("baidu", d1)
2. conn.hmget("baidu", "a1") //返回結果['b1']
3. conn.hmget("baidu", ["a1"]) //返回結果['b1']
4. conn.hmget("baidu", ["a1","a2"]) //返回結果['b1','b2']
5. conn.hmget("baidu", ["a1","a2","a3"]) //返回結果['b1','b2','b3']
引用
- redis內存分析工具
- https://neway6655.github.io/redis/2016/07/19/redis-memory-optimization-in-practice.html
- https://redisbook1e-gallery.readthedocs.io/en/latest/index.html