文章目錄
- hash
- 常用命令
- hset
- hget
- hexists
- hdel
- hkeys
- hvals
- hmget
- 壓縮
- hash和string
本篇總結的是,在Redis中的哈希數據類型
hash
在Redis內部本身,其實就是一種鍵值對的結構,而在key-value的value本身,其實也可以是一種哈希結構
而在value的哈希結構中,一般叫做是field-value結構
常用命令
hset
hset key field value [field value ...]
而在這里的value,只能是以字符串的形式出現,返回值是設置成功的數量:
127.0.0.1:6379> hset key1 f1 111
(integer) 1
127.0.0.1:6379> hset key1 f2 222 f3 333
(integer) 2
hget
這個命令只能獲取單個field的值:
hget key field
具體使用:
127.0.0.1:6379> hget key1 f1
"111"
127.0.0.1:6379> hget key1 f2
"222"
127.0.0.1:6379> hget key1 f1 f2
(error) ERR wrong number of arguments for 'hget' command
hexists
判斷hash中是否存在有指定的字段
時間復雜度是O(1),返回值是0表示沒有,返回值是1表示存在
127.0.0.1:6379> hexists key1 f1
(integer) 1
127.0.0.1:6379> hexists key1 f100
(integer) 0
hdel
刪除hash中指定的字段,del刪除的是key,而hdel刪除的是field
返回值也是本次操作刪除的字段的個數
hdel key field [field ...]
具體事例如下:
127.0.0.1:6379> hdel key1 f1 f2
(integer) 2
hkeys
先根據key找到對應的hash,再遍歷hash
127.0.0.1:6379> hkeys key1
1) "f3"
2) "f1"
3) "f2"
這個操作也是有一定的風險存在的,具體類似于之前講過的keys *,這個操作可能會因為某個key對應的hash結構中存在大量的數據,導致最終單線程模型下的Redis被阻塞
hvals
和hkeys相對,能夠獲取到hash中所有的value值
127.0.0.1:6379> hkeys key1
1) "f3"
2) "f1"
3) "f2"
127.0.0.1:6379> hvals key1
1) "333"
2) "111"
3) "222"
hmget
類似于之前的mget,一次可以查詢多個field
127.0.0.1:6379> hmget key f1 f2 f3
1) (nil)
2) (nil)
3) (nil)
127.0.0.1:6379> hmget key1 f1 f2 f3
1) "111"
2) "222"
3) "333"
上述的這些命令都是有一定風險的,可能會造成線程阻塞,原因在于這些命令都是要一次完成所有的操作,所以可能會阻塞Redis,那有沒有其他的方法呢?
這里介紹一個命令叫做hscan,它屬于是漸進式遍歷,相當于是敲一次命令遍歷一小部分,再敲一次,遍歷一小部分,連續執行多次,就可以完成整個的遍歷過程了,相當于是化整為零的操作
壓縮
談到哈希,就要先說說壓縮算法了,壓縮算法常見的有rar,zip,gzip,7z等等,而壓縮的本質,其實就是對于數據進行重新編碼,而針對于不同的數據,它們會有不同的特點,就可以依據這些不同的特點進行特定的設計,從而在編碼之后,就能夠達到縮小體積的效果
而這里想表述的含義是,ziplist也是如此,作為哈希的編碼方式,它內部的數據結構也是精心設計的,目的就是在于要節省內存空間,對于表示一個普通的哈希表來說,可能會造成一些內存浪費的問題,比如說,hash是一個數組,而作為數組,就會導致有些地方有元素,有些地方沒有元素,那么沒有元素的位置其實就是一種資源的浪費,那為了解決這樣的問題,就有了ziplist這種編碼方式
對于這種編碼方式來說,它的一個特點就是讀寫元素的效率會變低,速度會變慢,如果元素比較少還好,但是一旦元素達到一定的程度,此時就會導致效率明顯降低,所以此時就有了另外一種編碼方式叫做hashtable
總結
因此我們說:
- 哈希表的元素比較少的時候,就使用ziplist來表示,如果比較多就使用hashtable來表示
- 每個value的值長度都比較短的時候,就使用ziplist來表示,如果某個value的值太長了,就會轉換成hashtable
hash和string
那么現在的問題是,為什么要使用hash?難道使用JSON進行表示string難道不可以嗎?其實是可以的,但是這會面臨一個問題,比如要對于數據進行修改,需要把JSON先進行序列化,然后更改數據后再進行反序列化,這樣的成本顯然是比直接操作hash要高的,因此才引入了hash這樣的概念