目錄
前言
1.常見命令
1.1命令小結
1.2內(nèi)部編碼
2.使用場景
前言
幾乎所有的主流編程語言都提供了哈希(hash) 類型,它們的叫法可能是哈希、字典、關聯(lián)數(shù)組、映射。在Redis中,哈希類型是指值本身又是一個鍵值對結構,形如key= "key", value={{
field1, value1 }, ... {fieldN, valueN }}, Redis 鍵值對和哈希類型二者的關系可以用圖2-15來表示。
圖2-15字符串和哈希類型對比
哈希類型中的映射關系通常稱為field-value, 用于區(qū)分Redis整體的鍵值對(key-value) ,注意這里的value是指field對應的值,不是鍵(key) 對應的值,請注意value在不同上下文的作用。
1.常見命令
HSET
設置hash中指定的字段(field) 的值(value) 。
語法:
HSET key field value [field value ...]
命令有效版本: 2.0.0之后
時間復雜度:插入一組field為0(1),插入N組field為O(N)
返回值:添加的字段的個數(shù)。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HGET myhash field1
"Hello"
HGET
獲取hash中指定字段的值。
語法:
HGET key field
命令有效版本: 2.0.0之后
時間復雜度: O(1)
返回值:字段對應的值或者nil。
示例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HGET myhash field1
"foo"
redis> HGET myhash field2
(nil)
HEXISTS
判斷hash中是否有指定的字段。
語法:
HEXISTS key field
命令有效版本: 2.0.0之后
時間復雜度: O(1)
返回值: 1 表示存在,0表示不存在。
示例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HEXISTS myhash field1
(integer) 1
redis> HEXISTS myhash field2
(integer) 0
HDEL
刪除hash中指定的字段。
語法:
HDEL key field [field ...]
命令有效版本: 2.0.0之后
時間復雜度:刪除一個元素為0(1).刪除N個元素為O(N).
返回值:本次操作刪除的字段個數(shù)。
示例:
redis> HSET myhash field1 "foo"
(integer) 1
redis> HDEL myhash field1
(integer) 1
redis> HDEL myhash field2
(integer) 0
HKEYS
獲取hash中的所有字段。
語法:
HKEYS key
命令有效版本: 2.0.0之后
時間復雜度: O(N), N為field的個數(shù).
返回值:字段列表。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HKEYS myhash
1) "field1"
2) "field2"
HVALS?
獲取hash中的所有的值。
語法:
HVALS key
命令有效版本: 2.0.0 之后
時間復雜度: O(N), N為field的個數(shù).
返回值:所有的值。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HVALS myhash
1) "Hello"
2) "World"
HGETALL
獲取hash中的所有字段以及對應的值。
語法:
HGETALL key
命令有效版本: 2.0.0之后
時間復雜度: O(N), N為field的個數(shù).
返回值:字段和對應的值。
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
HMGET
一次獲取hash中多個字段的值。
語法:
HMGET key field [field ...]
命令有效版本: 2.0.0之后
時間復雜度:只查詢一個元素為0(1),查詢多個元素為O(N), N為查詢元素個數(shù).
返回值:字段對應的值或者nil.?
示例:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HMGET myhash field1 field2 nofield
1) "Hello"
2) "World"
3) (nil)
在使用HGETALL時,如果哈希元素個數(shù)比較多,會存在阻塞Redis的可能。如果開發(fā)人員只需要獲取部分field,可以使用HMGET,如果一定要獲取全部field,可以嘗試使用HSCAN命令,該命令采用漸進式遍歷哈希類型,HSCAN會在后續(xù)章節(jié)介紹。
HLEN
獲取hash中的所有字段的個數(shù)。
語法:
HLEN key
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HLEN myhash
(integer) 2
HSETNX
在字段不存在的情況下,設置hash中的字段和值。
語法:
HSETNX key field value
命令有效版本: 2.0.0之后
時間復雜度: 0(1)
返回值: 1表示設置成功,0表示失敗。
示例:
redis> HSETNX myhash field "Hello"
(integer) 1
redis> HSETNX myhash field "World"
(integer) 0
redis> HGET myhash field
"Hello"
HINCRBY
將hash中字段對應的數(shù)值添加指定的值。
語法:
HINCRBY key field increment
命令有效版本: 2.0.0之后
時間復雜度: 0(1)
返回值:該字段變化之后的值。
示例:
redis> HSET myhash field 5
(integer) 1
redis> HINCRBY myhash field 1
(integer) 6
redis> HINCRBY myhash field -1
(integer) 5
redis> HINCRBY myhash field -10
(integer) -5
HINCRBYFLOAT
HINCRBY的浮點數(shù)版本。
語法:
HINCRBYFLOAT key field increment
命令有效版本: 2.6.0之后
時間復雜度: 0(1)
返回值:該字段變化之后的值。
示例:
redis> HSET mykey field 10.50
(integer) 1
redis> HINCRBYFLOAT mykey field 0.1
"10.6"
redis> HINCRBYFLOAT mykey field -5
"5.6"
redis> HSET mykey field 5.0e3
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2
"5200"
1.1命令小結
表2-4是哈希類型命令的效果、時間復雜度,開發(fā)人員可以參考此表,結合自身業(yè)務需求和數(shù)據(jù)
大小選擇合適的命令。
表2-4哈希類型命令小結
1.2內(nèi)部編碼
哈希的內(nèi)部編碼有兩種:
ziplist (壓縮列表) : 當哈希類型元素個數(shù)小于hash-max -ziplist-entries配置(默認512個)、
同時所有值都小于hash-max- ziplist-value配置(默認 64字節(jié))時,Redis 會使用ziplist作為哈
希的內(nèi)部實現(xiàn),ziplist 使用更加緊湊的結構實現(xiàn)多個元素的連續(xù)存儲,所以在節(jié)省內(nèi)存方面比
hashtable更加優(yōu)秀。
●hashtable (哈希表) :當哈希類型無法滿足ziplist的條件時,Redis 會使用hashtable作為哈希
的內(nèi)部實現(xiàn),因為此時ziplist的讀寫效率會下降,而hashtable的讀寫時間復雜度為0(1)。
下面的示例演示了哈希類型的內(nèi)部編碼,以及響應的變化。
1)當field個數(shù)比較少且沒有大的value時,內(nèi)部編碼為ziplist:
127.0.0.1:6379> hmset hashkey f1 v1 f2 v2
OK
127.0.0.1:6379> object encoding hashkey
"ziplist"
2)當有value大于64字節(jié)時,內(nèi)部編碼會轉(zhuǎn)換為hashtable:
127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 bytes ... 省略 ..." 1
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"
3)當field個數(shù)超過512時,內(nèi)部編碼也會轉(zhuǎn)換為hashtable:?
127.0.0.1:6379> hmset hashkey f1 v1 h2 v2 f3 v3 ... 省略 ... f513 v513
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"
2.使用場景
圖2-16為關系型數(shù)據(jù)表記錄的兩條用戶信息,用戶的屬性表現(xiàn)為表的列,每條用戶信息表現(xiàn)為行。如果映射關系表示這兩個用戶信息,則如圖2-17所示。
圖2-16關系型數(shù)據(jù)表保存用戶信息
圖2-17映射關系表示用戶信息
相比于使用JSON格式的字符串緩存用戶信息,哈希類型變得更加直觀,并且在更新操作.上變得
更靈活??梢詫⒚總€用戶的id定義為鍵后綴,多對field-value對應用戶的各個屬性,類似如下偽代
碼:
●哈希類型是稀疏的,而關系型數(shù)據(jù)庫是完全結構化的,例如哈希類型每個鍵可以有不同的field, 而
關系型數(shù)據(jù)庫一旦添加新的列,所有行都要為其設置值,即使為null,如圖2-18所示。
●關系數(shù)據(jù)庫可以做復雜的關系查詢,而Redis去模擬關系型復雜查詢,例如聯(lián)表查詢、聚合查詢等基本不可能,維護成本高。
圖2-18關系型數(shù)據(jù)庫稀疏性
緩存方式對比
截至目前為止,我們已經(jīng)能夠用三種方法緩存用戶信息,下面給出三種方案的實現(xiàn)方法和優(yōu)缺點
分析。
1.原生字符串類型一使用字符串類型, 每個屬性一個鍵。
set user:1:name James
set user:1:age 23
set user:1:city Beijing
優(yōu)點:實現(xiàn)簡單,針對個別屬性變更也很靈活。
缺點:占用過多的鍵,內(nèi)存占用量較大,同時用戶信息在Redis中比較分散,缺少內(nèi)聚性,所以這種
方案基本沒有實用性。
2.序列化字符串類型,例如JSON格式
set user:1 經(jīng)過序列化后的??對象字符串
優(yōu)點:針對總是以整體作為操作的信息比較合適,編程也簡單。同時,如果序列化方案選擇合適,內(nèi)存的使用效率很高。
缺點:本身序列化和反序列需要一-定開 銷,同時如果總是操作個別屬性則非常不靈活。
3.hash類型:文章來源:http://www.zghlxwxcb.cn/news/detail-762618.html
hmset user:1 name James age 23 city Beijing
優(yōu)點:簡單、直觀、靈活。尤其是針對信息的局部變更或者獲取操作。
缺點:需要控制哈希在ziplist和hashtable兩種內(nèi)部編碼的轉(zhuǎn)換,可能會造成內(nèi)存的較大消耗。文章來源地址http://www.zghlxwxcb.cn/news/detail-762618.html
到了這里,關于redis—Hash哈希的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!