日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis:09---Hash对象

發布時間:2023/12/13 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis:09---Hash对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


一、哈希對象簡介

  • 幾乎所有的編程語言都提供了哈希(hash)類型,它們的叫法可能是哈希、字典、關聯數組

  • 哈希又稱散列

  • 在Redis中,哈希類型是指鍵值本身又是一個鍵值對結構,形如value={{field1,value1},...{fieldN,valueN}},Redis鍵值對和哈希類型二者的關系可以下圖表示

  • 一些特點:

    • 存儲多個鍵值對之間的映射,并且鍵值對不允許重復

    • 在某一個固定的key中,其對應value中的field也不允許重復

    • 散列存儲的值既可以是字符串也可以是數字值

    • 用戶同樣可以對散列存儲的數字值執行自增操作或自減操作

    • 散列在很多方面是一個微縮版的Redis,不少字符串命令都有相應的散列版本

    • 熟悉文檔數據庫的讀者可以將散列看作是文檔數據庫里面的文檔,而熟悉關系數據庫的讀者可以將散列看作是關系數據庫里面的行。因為“文檔、行、散列”這三者都允許用戶同時訪問或修改一個或多個域

  • 注意:哈希類型中的映射關系叫作field-value,注意這里的value是指field對應的值,不是鍵對應的值,請注意value在不同上下文的作用。

二、命令

常用命令

  • hset:設置值。如果設置成功會返回1,反之會返回0

hset key field value

? ? ??hsetnx:它們的關系就像set和setnx命令一樣,只不過作用域由鍵變為field

? ? ? ?

  • hget:獲取值。如果鍵或field不存在,返回nil

hget key field

好,到這里會有人好奇,這里到底是怎么樣的結構,能不能直觀的看到這些記錄,還是我在前幾篇文章說到的Redis DeskTop Manager可以查看

  • hdel:刪除field

    • hdel會刪除一個或多個field,返回結果為成功刪除field的個數

    • 直到某一個key對應的field全部刪除完全之后,該哈希對象才會被刪除

hdel key field [field ...]

  • hlen:計算fileld個數

hlen key

  • hmget、hmset:批量獲取/設置field-value

hmget key field [field ...] hmset key field value [field value ...]

  • hstrlen:計算value的字符串長度(需要Redis3.2以上)

hstrlen key field

其他命令

  • hincrby、hincrbyfloat:hincrby和hincrbyfloat,就像incrby和incrbyfloat命令一樣,但是它們的作用域是filed

  • hexists:判斷field是否存在。field存在返回1,不包含返回0

  • hkeys:獲取所有field

hkeys key

  • hvals:獲取所有值

hvals key
  • hgetall:獲取所有的field-value

hgetall key

  • 提示:在使用hgetall時,如果哈希元素個數比較多,會存在阻塞Redis的可能。 如果開發人員只需要獲取部分field,可以使用hmget,如果一定要獲取全部 field-value,可以使用hscan命令,該命令會漸進式遍歷哈希類型.

  • 下圖給出了哈希類型命令的時間復雜度:

三、內部編碼

  • 哈希類型的內部編碼有兩種:

    • ziplist(壓縮列表):當哈希類型元素個數小于hash-max-ziplist-entries 配置(默認512個)、同時所有值都小于hash-max-ziplist-value配置(默認64 字節)時,Redis會使用ziplist作為哈希的內部實現,ziplist使用更加緊湊的 結構實現多個元素的連續存儲,所以在節省內存方面比hashtable更加優秀

    • hashtable(哈希表):當哈希類型無法滿足ziplist的條件時,Redis會使 用hashtable作為哈希的內部實現,因為此時ziplist的讀寫效率會下降,而 hashtable的讀寫時間復雜度為O(1)

演示說明

  • 當field個數比較少且沒有大的value時,內部編碼為ziplist:

  • 當有value大于64字節,內部編碼會由ziplist變為hashtable:

  • 當field個數超過512,內部編碼也會由ziplist變為hashtable

四、字符串和散列的比較與選擇

散列的優點

  • 散列的最大優勢,只需要在數據庫里面創建一個鍵,就可以把任意多的字段和值存儲到散列里面

字符串的優點

  • 雖然散列鍵命令和字符串鍵命令在部分功能上有重合的地方,但是字符串鍵命令提供的操作比散列鍵命令更為豐富。比如,字符串能夠使用 SETRANGE 命令和 GETRANGE 命令設置或者讀取字符 串值的其中一部分,或者使用 APPEND 命令將新內容追加到字符串值的末尾,而散列鍵并不支持 這些操作

  • 再比如我們要設置鍵過期時間,鍵過期時間是針對整個鍵的,用戶無法為散列中的不同字段設置不 同的過期時間,所以當一個散列鍵過期的時候,他包含的所有字段和值都會被刪除。與此相反,如 果用戶使用字符串鍵存儲信息項,就不會遇到這樣的問題——用戶可以為每個字符串鍵分別設置不 同的過期時間,讓它們根據實際的需要自動被刪除

字符串和散列的選擇

  • 使用場景對比:

    • 如果程序需要為單個數據項單獨設置過期的時間,那么使用字符串鍵。

    • 如果程序需要對數據項執行諸如 SETRANGE、GETRANGE 或者 APPEND 等操作,那么優 先考慮使用字符串鍵。當然,用戶也可以選擇把數據存儲在散列中,然后將類似 SETRANG E、GETRANGE 這樣的操作交給客戶端執行

    • 如果程序需要存儲的數據項比較多,并且你希望盡可能地減少存儲數據所需的內存,就應該優 先考慮使用散列鍵

    • 如果多個數據項在邏輯上屬于同一組或者同一類,那么應該優先考慮使用散列鍵

五、使用場景

短網址生成程序

  • 此時我們可以根據該短鏈接查詢到具體的源網址,并記錄點擊次數

存儲信息

  • 下圖為關系型數據表記錄的兩條用戶信息,用戶的屬性作為表的列, 每條用戶信息作為行

  • 如果將其用哈希類型存儲,如下圖所示:

  • 相比于使用字符串序列化緩存用戶信息,哈希類型變得更加直觀,并且在更新操作上會更加便捷。可以將每個用戶的id定義為鍵后綴,多對fieldvalue對應每個用戶的屬性,類似如下偽代碼:

UserInfo?getUserInfo(long?id){//?用戶id作為key后綴userRedisKey?=?"user:info:"?+?id;//?使用hgetall獲取所有用戶信息映射關系userInfoMap?=?redis.hgetAll(userRedisKey);UserInfo?userInfo;if?(userInfoMap?!=?null)?{//?將映射關系轉換為UserInfouserInfo?=?transferMapToUserInfo(userInfoMap);}?else?{//?從MySQL中獲取用戶信息userInfo?=?mysql.get(id);//?將userInfo變為映射關系使用hmset保存到Redis中redis.hmset(userRedisKey,?transferUserInfoToMap(userInfo));//?添加過期時間redis.expire(userRedisKey,?3600);}return?userInfo;}
  • 但是需要注意的是哈希類型和關系型數據庫有兩點不同之處:

    • 哈希類型是稀疏的,而關系型數據庫是完全結構化的,例如哈希類型 每個鍵可以有不同的field,而關系型數據庫一旦添加新的列,所有行都要為 其設置值(即使為NULL),如下圖所示

    • 關系型數據庫可以做復雜的關系查詢,而Redis去模擬關系型復雜查詢 開發困難,維護成本高

三種方案

  • 開發人員需要將兩者的特點搞清楚,才能在適合的場景使用適合的技術。到目前為止,我們已經能夠用三種方法緩存用戶信息,下面給出三種方案的實現方法和優缺點分析

  • ①原生字符串類型:每個屬性一個鍵

    • 優點:簡單直觀,每個屬性都支持更新操作

    • 缺點:占用過多的鍵,內存占用量較大,同時用戶信息內聚性比較差, 所以此種方案一般不會在生產環境使用

set user:1:name tom set user:1:age 23 set user:1:city beijin
  • ②序列化字符串類型:將用戶信息序列化后用一個鍵保存。

    • 優點:簡化編程,如果合理的使用序列化可以提高內存的使用效率

    • 缺點:序列化和反序列化有一定的開銷,同時每次更新屬性都需要把全 部數據取出進行反序列化,更新后再序列化到Redis中

set user:1 serialize(userInfo)
  • ③哈希類型:每個用戶屬性使用一對field-value,但是只用一個鍵保存

    • 優點:簡單直觀,如果使用合理可以減少內存空間的使用

    • 缺點:要控制哈希在ziplist和hashtable兩種內部編碼的轉換,hashtable會消耗更多內存

hmset user:1 name tomage 23 city beijing

不過對于我而言,我經常用到的是string,方便,快捷,一般是存儲一些玩家的登錄緩存信息,或者一些全服跨服戰斗的相關數據

總結

以上是生活随笔為你收集整理的Redis:09---Hash对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。