文章目錄
- 表示形式
- 命令
- HSET 和 HGET
- HEXISTS
- HDEL
- HKEYS
- HVALS
- HGETALL
- HMGET
- HLEN
- HSETNX
- HINCRBY
- HINCRBYFLOAT
- 命令小結
- 內部編碼
表示形式
Redis
自身已經是鍵值對結構了
Redis
自身的鍵值對就是通過哈希的方式來組織的
把 key
這一層組織完成之后,到了 value
這一層,value
這一層也可以是哈希
- 哈希類型中的映射關系通常稱為
field-value
,用于區分Redis
整體的鍵值對(key-value
),注意這里的value
是指field
對應的值,不是 key 對應的值,注意value
在不同上下文的作用
命令
HSET 和 HGET
設置/獲取 hash
中指定的字段(field
)的值(value
)
語法:
HSET key field value [field value...]HGET key field
HSET
的返回值是設置成功的鍵值對(field-value
)的個數- 時間復雜度: O ( 1 ) O(1) O(1)
HEXISTS
判斷 hash
中是否有指定的字段
語法:
HEXISTS key field
- 返回值:
1
表示存在,0
表示不存在 - 時間復雜度: O ( 1 ) O(1) O(1)
HDEL
刪除 hash
中指定的字段
del
刪除的是key
hdel
刪除的是field
語法:
HDEL key field [field...]
- 返回值是本次刪除的字段個數
- 時間復雜度:刪除一個元素為 O ( 1 ) O(1) O(1),刪除 N N N 個位 O ( N ) O(N) O(N)(幾十幾百個就視為 1)
HDEL
是刪除key
對應的value
(field-value
) 中的鍵值對field
DEL
是直接刪除key
對應的value
(里面所有的鍵值對全刪)
HKEYS
獲取 hash
中的所有字段
語法:
HKEYS key
- 這個操作,會先根據
key
找到對應的hash
( O ( 1 ) O(1) O(1)),然后再遍歷hash
( O ( N ) O(N) O(N), N N N 為hash
的元素個數)
談到 O ( N ) O(N) O(N),有的時候, N N N 表示:
Redis
整體key
的個數- 當前命令中
key
的個數 (因為我們一般不會弄太多key
,所以一般可以直接看做 O ( 1 ) O(1) O(1))- 當前
key
對應的value
里面的元素個數- …
HVALS
獲取 hash 中的所有的值
語法:
HVALS key
- 時間復雜度: O ( N ) O(N) O(N)( N N N 是哈希的元素個數,如果哈希非常大,這個操作就可能導致
Redis
服務器被阻塞住)
HGETALL
獲取 hash
中的所有字段以及對應的值
- 相當于結合了
HKEYS
和HVALS
語法:
HGETALL key
- 時間復雜度: O ( N ) O(N) O(N)( N N N 是哈希的元素個數,如果哈希非常大,這個操作就可能導致
Redis
服務器被阻塞住)
這個操作,還是風險比較大。多數情況下,不需要查詢所有的
field
,可能只查其中的幾個key
HMGET
一次獲取 hash
中多個字段的值
語法:
HMGET key field [field...]
- 時間復雜度:刪除一個元素為 O ( 1 ) O(1) O(1),刪除 N N N 個位 O ( N ) O(N) O(N)(幾十幾百個就視為 1)
- 返回值:字段對應的值或者
nil
- 上述
HKEYS
、HVALS
、HGETALL
都是存在一定風險的。hash
元素個數太多,執行的時間就會比較長,從而阻塞Redis
- 一條命令,就能完成所有的遍歷操作
HSCAN
遍歷Redis
的hash
,“漸進式遍歷“
- 敲一次命令,遍歷一小部分
- 再敲一次命令,再遍歷一小部分
- …
- 連續執行多次,就可以完成整個遍歷過程(化整為零)
ConcurrentHashMap
線程安全的哈希表
HLEN
獲取 hash
中的所有字段的個數
語法:
HLEN key
- 時間復雜度: O ( 1 ) O(1) O(1)
- 返回值:字段個數
HSETNX
在字段不存在的情況下,設置 hash
中的字段和值
語法:
HSETNX key field value
- 時間復雜度: O ( 1 ) O(1) O(1)
- 返回值:1 表示成功,0 表示失敗
HINCRBY
將 hash
中字段對應的數字添加指定的值
語法:
HINCRBY key field increment
- 時間復雜度: O ( 1 ) O(1) O(1)
- 返回值:該字段變化后的值
HINCRBYFLOAT
HINCRBY
的浮點數版本
語法:
HINCRBYFLOAT key field increment
- 時間復雜度: O ( 1 ) O(1) O(1)
- 返回值:該字段變化后的值
命令小結
內部編碼
哈希的內部編碼有兩種:
ziplist
:壓縮列表hashtable
:哈希表
壓縮:
rar
zip
gzip
7z
- …
這是一些具體的壓縮算法。
壓縮的本質,是針對數據進行重新編碼。不同的數據,有不同的特點,結合這些特點,進行精妙的設計,重新編碼之后,就能夠縮小體積
比如,現在有字符串:
abcccddddeeeee
- 重新編碼表示:
1a2b3c4d5e
- 重新編碼后的結果就比原來的短了(粗糙)
ziplist
內部的數據結構也是精心設計的(目的是節省內存空間)
- 表示一個普通的
hash
表,可能會浪費一定的空間(hash
首先是一個數組,數組上有些位置有元素,有些沒有元素) - 付出的代價是進行讀寫元素,速度是比較慢的。如果元素個數少,慢的不明顯,但如果元素多了,慢就會雪上加霜
如果:
- 哈希中的元素個數比較少,使用
ziplist
表示;元素較多,就用hashtable
來表示 - 每個
value
的值,長度都比較短,使用ziplist
表示;如果某個value
的長度太長了,也會轉換成hashtable
- 可以在
redis。conf
文件中,調整hash-max-ziplist-entries
配置和hash-max-ziplist-value
配置