Redis 避不開的五種數據結構--hash

原文鏈接:https://my.oschina.net/editorial-story/blog/2120649

哈希類型

大部分語言基本都提供了哈希類型,如 Java 語言中的 Map 類型及 Python 語言中的字典類型等等。雖然語言不同,但它們基本使用都是一樣的,也就是都是鍵值對結構的。例如:

value={{field1, value1}

通過下圖可以直觀感受一下字符串類型和哈希類型的區別:

Redis 中哈希類型都是鍵值對結構的,所以要特別注意這裏的 value 並不是指 Redis 中 key 的 value,而是哈希類型中的 field 所對應的 value。

命令

下面我們還是和介紹字符串類型一樣,瞭解一下 Redis 中哈希類型的相關命令。

1.設置值

hset key field value

我們看上圖執行的命令知道,hset 命令也是有返回值的。如果 hset 命令設置成功,則返回 1,否則返回 0。除此之外 Redis 也爲哈希類型提供了 hsetnx 命令。在前文對字符串的介紹中,我們知道 nx 命令只有當 key 不存在的時候,才能設置成功,同樣的,hsetnx 命令在 field 不存在的時候,才能設置成功。

2.獲取值

hget key field

我們看 hget 命令和 get 有很大的不同,get 命令在獲取的時候,只要寫一個名字就可以了,而 hget 命令則要寫兩個名字,第一個名字是 key,第二個名字是 field。當然 key 或者 field 不存在時,返回的結果都是 nil。

3.刪除 field

hdel key field [field ...]

hdel 命令刪除時候,也會有返回值,並且這個返回就是成功刪除 field 的個數。當 field 不存在時,並不會報錯,而是直接返回 0。

4.計算 field 個數

hlen key

hlen 命令返回的就是當前 key 中 field 的個數,如果 key 不存在,則返回 0。

5.批量設置或獲取 field-value

hmget key field [field ...]

hmset key field value [field value ...]

hmset 命令和 hmget 命令分別是批量設置和獲取值的,hmset 命令沒有什麼要注意的,但 hmget 命令要特別注意,當我們獲取一個不存在的 key 或者不存在的 field 時,Redis 並不會報錯,而是返回 nil。並且有幾個 field 不存在,則 Redis 返回幾個 nil。

6.判斷 field 是否存在

hexists key field

當執行 hexists 命令時,如果當前 key 包括 field,則返回 1,否則返回 0。

7.獲取所有 field

hkeys key

8.獲取所有 value

hvals key

9.獲取所有的 field-value

hgetall key

hgetall 命令會返回當前 key 中的所有 field-value,並按照順序依次返回。

10.計數

hincrby key field increment

hincrbyfloat key field increment

hincrby 命令和 incrby 命令的使用功能基本一樣,都是對值進行增量操作的,唯一不同的就是 incrby 命令的作用域是 key,而 hincrby 命令的作用域則是 field。

11.計算 value 的字符串長度

hstrlen key field

hstrlen 命令返回的是當前 key 中 field 中字符串的長度,如果當前 key 中沒有 field 則返回 0。

內部編碼

Redis 哈希類型的內部編碼有兩種,它們分別是:

  • ziplist(壓縮列表):當哈希類型中元素個數小於 hash-max-ziplist-entries 配置(默認 512 個),同時所有值都小於 hash-max-ziplist-value 配置(默認 64 字節)時,Redis 會使用 ziplist 作爲哈希的內部實現。
  • hashtable(哈希表):當上述條件不滿足時,Redis 則會採用 hashtable 作爲哈希的內部實現。

下面我們通過以下命令來演示一下 ziplist 和 hashtable 這兩種內部編碼。

當 field 個數比較少並且 value 也不是很大時候 Redis 哈希類型的內部編碼爲 ziplist:

當 value 中的字節數大於 64 字節時(可以通過 hash-max-ziplist-value 設置),內部編碼會由 ziplist 變成 hashtable。

當 field 個數超過 512(可以通過 hash-max-ziplist-entries 參數設置),內部編碼也會由 ziplist 變成 hashtable。

由於直接手動創建 512 個 field 不方便,爲了更好的驗證該功能,我將用程序的方式,動態創建 512 個 field 來驗證此功能,下面爲具體的代碼:

import redis
r = redis.Redis(host='127.0.0.1', port=6379)
print('Key爲【userinfo】的字節編碼爲【%s】' % r.object('encoding', 'userinfo').decode('utf-8'))
for i in range(1,513):    
    r.hset('userinfo', i, '吉林烏拉')
print('Key爲【userinfo】的字節編碼爲【%s】' % r.object('encoding', 'userinfo').decode('utf-8'))
Key爲【userinfo】的字節編碼爲【ziplist】
Key爲【userinfo】的字節編碼爲【hashtable】

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章