一、redis的數(shù)據(jù)類型
1、常規(guī)類型
- String(字符串):最基本的數(shù)據(jù)結(jié)構(gòu),可以存儲任何類型的字符串、數(shù)字或二進(jìn)制數(shù)據(jù)。
- Hash(哈希表):類似于關(guān)聯(lián)數(shù)組或字典,可以存儲多個(gè)字段和對應(yīng)的值,常用于存儲對象屬性或配置信息。
- List(列表):一個(gè)有序的字符串列表,支持在列表兩端進(jìn)行插入和刪除操作,還提供了多種操作,如查找、裁剪、排序等。
- Set(集合):一個(gè)無序的字符串集合,支持添加、刪除、查找和求交、并、差等操作,還提供了多種操作,如求隨機(jī)元素、判斷元素是否存在等。
- ZSet(有序集合):和 Set 類型相似,但是每個(gè)元素都有一個(gè)分?jǐn)?shù)(score),根據(jù)分?jǐn)?shù)進(jìn)行排序,可以支持按照分?jǐn)?shù)范圍進(jìn)行查找、插入和刪除操作。
2、官網(wǎng)最全類型
Redis支持的數(shù)據(jù)類型概述。
Redis 是一個(gè)數(shù)據(jù)結(jié)構(gòu)服務(wù)器。Redis 的核心提供了一系列本機(jī)數(shù)據(jù)類型,可幫助您解決從緩存到隊(duì)列再到事件處理的各種問題。下面是每種數(shù)據(jù)類型的簡短描述,以及更廣泛的概述和命令參考的鏈接。
如果您想嘗試每種數(shù)據(jù)結(jié)構(gòu)的綜合教程,請參閱下面的概述頁面。
String
Redis String是最基本的 Redis 數(shù)據(jù)類型,表示字節(jié)序列。有關(guān)更多信息,請參閱:
- Redis 字符串概述
- Redis字符串命令參考
List
Redis List是按插入順序排序的字符串列表。有關(guān)更多信息,請參閱:
- Redis 列表概述
- Redis列表命令參考
Sets
Redis 集是唯一字符串的無序集合,其作用類似于您最喜歡的編程語言中的集(例如,JAVA HashSets、Python/ target=_blank class=infotextkey>Python 集等)。使用 Redis 集合,您可以在 O(1) 時(shí)間內(nèi)添加、刪除和測試是否存在(換句話說,無論集合元素的數(shù)量有多少)。有關(guān)更多信息,請參閱:
- Redis 集概述
- Redis set命令參考
Hash
Redis 哈希是建模為字段值對集合的記錄類型。因此,Redis 哈希類似于Python 字典、Java HashMap和Ruby 哈希。有關(guān)更多信息,請參閱:
- Redis 哈希概述
- Redis 哈希命令參考
Sorted sets
Redis 排序集是唯一字符串的集合,它們通過每個(gè)字符串的關(guān)聯(lián)分?jǐn)?shù)來維護(hù)順序。有關(guān)更多信息,請參閱:
- Redis 排序集概述
- Redis有序集命令參考
Streams
Redis Streams是一種數(shù)據(jù)結(jié)構(gòu),其作用類似于僅附加日志。流有助于按事件發(fā)生的順序記錄事件,然后將它們聯(lián)合起來進(jìn)行處理。有關(guān)更多信息,請參閱:
- Redis 流概述
- Redis Streams 命令參考
Geospatial indexes
Redis Geospatial indexes對于查找給定地理半徑或邊界框內(nèi)的位置非常有用。有關(guān)更多信息,請參閱:
- Redis 地理空間索引概述
- Redis 地理空間索引命令參考
Bitmaps
Redis Bitmaps允許您對字符串執(zhí)行按位運(yùn)算。有關(guān)更多信息,請參閱:
- Redis 位圖概述
- Redis 位圖命令參考
Bitfields
Redis Bitfields有效地對字符串值中的多個(gè)計(jì)數(shù)器進(jìn)行編碼。位域提供原子獲取、設(shè)置和增量操作,并支持不同的溢出策略。有關(guān)更多信息,請參閱:
- Redis 位域概述
- 命令BITFIELD。
HyperLogLog
Redis HyperLogLog數(shù)據(jù)結(jié)構(gòu)提供大型集合的基數(shù)(即元素?cái)?shù)量)的概率估計(jì)。有關(guān)更多信息,請參閱:
- Redis HyperLogLog概述
- Redis HyperLogLog命令參考
Extensions
要擴(kuò)展所包含數(shù)據(jù)類型提供的功能,請使用以下選項(xiàng)之一:
- 在 Lua 中編寫您自己的自定義服務(wù)器端函數(shù)。
- 使用模塊 API編寫您自己的 Redis 模塊或查看社區(qū)支持的模塊。
- 使用Redis Stack提供的JSON、查詢、時(shí)間序列和其他功能。
3、Redis內(nèi)部編碼
在 Redis 中,"內(nèi)部編碼"指的是數(shù)據(jù)在內(nèi)存中以何種方式進(jìn)行編碼和存儲,以便在運(yùn)行時(shí)有效地管理和操作數(shù)據(jù)。Redis 為每種數(shù)據(jù)類型選擇了一組不同的編碼方式,以根據(jù)數(shù)據(jù)的特點(diǎn)和使用情況來最大程度地減少內(nèi)存占用并提高性能。
每種數(shù)據(jù)類型都可能有多種內(nèi)部編碼方式,這些編碼方式對應(yīng)不同的數(shù)據(jù)結(jié)構(gòu),以適應(yīng)不同的數(shù)據(jù)場景。例如,對于字符串類型,Redis 可能根據(jù)字符串的內(nèi)容和長度選擇不同的內(nèi)部編碼方式。而對于哈希類型,Redis 可能根據(jù)字段數(shù)量和字段值的長度來選擇內(nèi)部編碼方式。
內(nèi)部編碼的選擇是自動進(jìn)行的,由 Redis 在運(yùn)行時(shí)根據(jù)數(shù)據(jù)的特點(diǎn)和存儲需求來動態(tài)地切換。這種動態(tài)切換使 Redis 能夠在不同的情況下優(yōu)化內(nèi)存使用和性能,從而更好地滿足不同應(yīng)用場景的需求。
了解內(nèi)部編碼可以幫助您更好地理解 Redis 如何管理數(shù)據(jù),并在設(shè)計(jì)和優(yōu)化應(yīng)用程序時(shí)做出更明智的決策。
我們可以通過命令object encoding 來查看對象的內(nèi)部編碼:
> SET mystring "123"
OK
> OBJECT ENCODING mystring
int
以下是常見對象類型及對應(yīng)的內(nèi)部編碼:
字符串類型 (string):
- 內(nèi)部編碼:根據(jù)字符串內(nèi)容和長度,可能使用 int、embstr、raw 三種編碼方式。
- 說明:int 編碼用于存儲可以表示為整數(shù)的字符串,embstr 編碼用于短字符串,raw 編碼用于一般字符串。
哈希類型 (hash):
- 內(nèi)部編碼:根據(jù)哈希表中字段數(shù)量和字段值的長度,可能使用 ziplist、hashtable 兩種編碼方式。
- 說明:ziplist 編碼用于字段較少或字段值較短的情況,hashtable 編碼用于字段較多或字段值較長的情況。
列表類型 (list):
- 內(nèi)部編碼:根據(jù)列表長度和元素的長度,可能使用 ziplist、linkedlist 兩種編碼方式。
- 說明:ziplist 編碼用于短列表,linkedlist 編碼用于較長的列表。
集合類型 (set):
- 內(nèi)部編碼:根據(jù)集合中元素?cái)?shù)量和元素的長度,可能使用 intset、hashtable 兩種編碼方式。
- 說明:intset 編碼用于存儲整數(shù)成員的集合,hashtable 編碼用于存儲字符串成員的集合。
有序集合類型 (zset 或 sortedset):
- 內(nèi)部編碼:根據(jù)有序集合中元素?cái)?shù)量和元素的長度,可能使用 ziplist、skiplist 兩種編碼方式。
- 說明:ziplist 編碼用于短有序集合,skiplist 編碼用于較長的有序集合。
二、String與Hash如何選擇?
Redis作為一種流行的內(nèi)存數(shù)據(jù)存儲,提供了多種數(shù)據(jù)結(jié)構(gòu)來適應(yīng)不同的用例。其中,String和Hash是Redis中最基礎(chǔ)的兩種數(shù)據(jù)結(jié)構(gòu)。雖然它們都是Redis的重要組成部分,但它們各自具有不同的用途和性能特點(diǎn)。在本文中,我們將深入探討在應(yīng)用程序需求下如何在String和Hash之間做出選擇。
1、String數(shù)據(jù)結(jié)構(gòu)
String是Redis中最簡單的數(shù)據(jù)類型,可以存儲文本、整數(shù)和浮點(diǎn)數(shù)。在選擇使用String數(shù)據(jù)結(jié)構(gòu)時(shí),應(yīng)考慮以下場景:
- 單一值存儲: 如果只需要為給定的鍵存儲單個(gè)值,例如緩存計(jì)算結(jié)果或存儲用戶偏好設(shè)置,那么String是首選的選項(xiàng)。
- 原子操作: Redis對String提供原子操作,允許您對鍵的數(shù)值進(jìn)行遞增、遞減和操作。這對于實(shí)現(xiàn)計(jì)數(shù)器、鎖和簡單分析非常有用。
- 緩存簡單數(shù)據(jù): 如果要緩存不需要復(fù)雜結(jié)構(gòu)的數(shù)據(jù),如html片段或序列化對象,String能夠提供高效的存儲和檢索。
2、Hash數(shù)據(jù)結(jié)構(gòu)
相對于String,Hash是一種更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu),它允許您在單個(gè)鍵下存儲字段-值對。以下情況考慮使用Hash數(shù)據(jù)結(jié)構(gòu):
- 結(jié)構(gòu)化數(shù)據(jù): Hash非常適合存儲結(jié)構(gòu)化數(shù)據(jù),比如用戶資料,其中每個(gè)字段對應(yīng)于特定的屬性(如用戶名、電子郵件、年齡)。
- 部分更新: 當(dāng)需要更新對象的特定字段而不影響整個(gè)數(shù)據(jù)結(jié)構(gòu)時(shí),Hash表現(xiàn)出色。這比使用String替換整個(gè)值更加高效。
- 減少鍵空間混亂: 使用Hash,您可以將相關(guān)字段分組在一個(gè)鍵下,而不是為實(shí)體的每個(gè)字段使用單獨(dú)的String鍵,從而使鍵空間更加有序。
使用場景:
String 數(shù)據(jù)類型:
- 適用于存儲單個(gè)值,如用戶的 session 數(shù)據(jù)、計(jì)數(shù)器、配置信息等。
- 不需要進(jìn)行復(fù)雜的結(jié)構(gòu)化查詢或數(shù)據(jù)處理。
- 適合存儲簡單的字符串?dāng)?shù)據(jù),如緩存、驗(yàn)證碼等。
Hash 數(shù)據(jù)類型:
- 適用于存儲多個(gè)字段的數(shù)據(jù),類似于關(guān)聯(lián)數(shù)組或?qū)ο蟆?/li>
- 需要進(jìn)行復(fù)雜的結(jié)構(gòu)化查詢和數(shù)據(jù)處理,如用戶信息、商品信息、文章內(nèi)容等。
- 可以有效地對單個(gè)字段進(jìn)行讀寫操作,避免整個(gè)對象的序列化和反序列化開銷。
性能分析:
String 數(shù)據(jù)類型性能:
- 讀寫操作非常高效,可以在常數(shù)時(shí)間內(nèi)完成。
- 適用于簡單的 GET 和 SET 操作,特別是對于鍵的更新頻率較低的情況。
- 在存儲大量短期數(shù)據(jù),如緩存數(shù)據(jù)時(shí),表現(xiàn)出色。
Hash 數(shù)據(jù)類型性能:
- 適用于需要存儲和操作多個(gè)字段的數(shù)據(jù),不需要對整個(gè)對象進(jìn)行讀寫操作。
- Hash 在存儲大量字段時(shí)可以節(jié)省內(nèi)存,因?yàn)?Redis 對每個(gè)字段會采用類似字典的結(jié)構(gòu)進(jìn)行存儲。
- 對于大規(guī)模的查詢和更新操作,Hash 數(shù)據(jù)類型可以更高效地進(jìn)行。
- 注意,當(dāng) Hash 內(nèi)部字段數(shù)量較少時(shí),可能會造成內(nèi)存浪費(fèi),因?yàn)?Hash 需要一定的額外空間來存儲字段信息。
在實(shí)際應(yīng)用中,往往會結(jié)合使用不同的 Redis 數(shù)據(jù)類型來滿足不同的需求。例如,對于用戶的基本信息,可以使用 Hash 數(shù)據(jù)類型存儲用戶 ID 到詳細(xì)信息的映射關(guān)系;而對于用戶的 session 數(shù)據(jù),可以使用 String 數(shù)據(jù)類型存儲單個(gè)用戶的 session 信息。
在做選擇時(shí),要根據(jù)實(shí)際需求權(quán)衡存儲結(jié)構(gòu)、查詢和更新的頻率、數(shù)據(jù)量等因素。需要強(qiáng)調(diào)的是,Redis 的性能在大部分情況下都非常出色,但最佳選擇會取決于您的具體應(yīng)用需求。最好的方式是在實(shí)際場景中進(jìn)行測試和基準(zhǔn)測試,以確定最適合您應(yīng)用的數(shù)據(jù)類型。