網(wǎng)站首頁 編程語言 正文
String
簡介
String是 Redis 最基本的類型,你可以理解成與Memcached 一模一樣的類型,一個 key 對應(yīng)一個 value。
String 類型是二進制安全的
。意味著 Redis 的 string 可以包含任何數(shù)據(jù)。比如:jpg圖像或者序列化的對象。
String 類型是 Redis 最基本的數(shù)據(jù)類型,一個 Redis中字符串value最多可以是512M
。
常用命令
set <key> <value>
添加鍵值對。
- NX:當(dāng)數(shù)據(jù)庫中key不存在時,可以將 key-value 添加數(shù)據(jù)庫。
setnx key value
。 - XX:當(dāng)數(shù)據(jù)庫中key存在時,可以將 key-value 添加數(shù)據(jù)庫,與NX參數(shù)互斥。
- EX:key 的超時秒數(shù)。
- PX:key 的超時毫秒數(shù),與EX互斥。
get <key>
查詢對應(yīng)鍵值。append <key> <value>
將給定的<value>追加到原值的末尾。strlen <key>
獲得值得長度。setnx <key> <value>
只有在 key 不存在時,設(shè)置 key 的值。incr <key>
將 key 中存儲的數(shù)字值增1。decr <key>
將key 中存儲的數(shù)字值減1,只能對數(shù)字值操作,如果為空,新增值為-1。incrby或者decrby <key> <步長>
將key 中存儲的數(shù)字值遞增或遞減。自定義步長。mset <key1> <value1> <key2> <value2> ...
同時獲取一個或多個 value。msetnx <key1> <value1> <key2> <value2> ...
同時設(shè)置一個或多個 key-value 對,當(dāng)且僅當(dāng)所有給定 key 都不存在。原子性,有一個失敗則都失敗。
getrange <key> <起始位置> <結(jié)束位置>
獲得值的范圍,類型java中的substring,前包,后包。setrange <key> <起始位置> <value>
用<value> 覆蓋<key>所存儲的字符串值,從<起始位置>開始(索引從0開始
)。setex <key> <過期時間> <value>
設(shè)置鍵值的同時,設(shè)置過期時間,單位秒。getset <key> <value>
以新?lián)Q舊,設(shè)置新值的同時獲得舊值。
數(shù)據(jù)結(jié)構(gòu)
String 的數(shù)據(jù)結(jié)構(gòu)為簡單動態(tài)字符串(Simple Dynamic String,縮寫SDS)。是可以修改的字符串,內(nèi)部結(jié)構(gòu)是實現(xiàn)上類似于Java的ArrayList,采用預(yù)分配冗余空間的方式來減少內(nèi)存的頻繁分配。
如圖中所示,內(nèi)部為當(dāng)前字符串實際分配的空間 capacity 一般要高于實際字符串長度len。當(dāng)字符串長度小于1M時,擴容都是加倍現(xiàn)有的空間,如果超過 1M,擴容時一次只會擴 1M 的空間。需要注意的時字符串最大長度為 512M。
List
簡介
單鍵多值
Redis 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
它的底層實際是個雙向鏈表
,對兩端的操作性能很高,通過索引下標(biāo)的操作中間的節(jié)點性能會較差。
常用命令
lpush/rpush <key> <value1> <value2> ......
從左邊/右邊插入一個或多個值。lpop/rpop <key>
從左邊/右邊取出一個值,并刪除。值在鍵在rpoplpush <key1> <key2>
從<key1>列表取出一個值,插在<key2>列表的左邊。lrange <key1> <start> <stop>
按照索引下標(biāo)獲得元素(從左到右)。lrange mylist 0 -1
0左邊第一個,-1右邊第一個,(0 -1表示獲取所有)。lindex <key> <index>
按照索引下標(biāo)獲得元素(從左到右)。llen <key>
獲得列表長度。linsert <key> before <value> <newvalue>
在<value>后面插入<newvalue>值。lrem <key> <n> <value>
從左邊刪除n個value(從左到右)。lset <key> <index> <value>
將列表key下標(biāo)為index的值替換成value。
數(shù)據(jù)結(jié)構(gòu)
List的數(shù)據(jù)結(jié)構(gòu)為快速鏈表quickList
首先在列表元素較少的情況下會使用一塊連續(xù)的內(nèi)存存儲,這個結(jié)構(gòu)是ziplist,也即是壓縮列表。
它將所有的元素緊挨著一起存儲,分配的是一塊連續(xù)的內(nèi)存。
當(dāng)數(shù)據(jù)量比較多的時候才會改成quicklist。
因為普通的鏈表需要的的附加指針空間太大,會比較浪費空間。比如:列表里存的只是int類型的數(shù)據(jù),結(jié)構(gòu)上還需要兩個額外的指針prev和next。
Redis將鏈表和ziplist結(jié)合起來組成了quicklist。也就是將多個ziplist使用雙向指針串起來使用。這樣既滿足了快速的插入刪除性能,又不會出現(xiàn)太大的空間冗余。
Set
簡介
Redis set 對外提供的功能與list類似是一個列表的功能,特殊之處在于set是可以自動排重
的,當(dāng)你需要存儲一個列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時,set 是一個很好的選擇,并且 set 提供了判斷某個成員是否在一個 set集合內(nèi)的重要接口,這也是 list 所不能提供的。
Redis 的 set 時string類型的無序集合
。它底層其實是一個value為null的hash表
,所以添加、刪除、查找的復(fù)雜度都是 O(1)
。
一個算法,隨著數(shù)據(jù)的增加,執(zhí)行時間的長短,如果是 O(1),數(shù)據(jù)增加,查找數(shù)據(jù)的時間不變。
常用命令
sadd <key> <value1> <value2> ......
將一個或多個member元素加入到集合key中,已經(jīng)存在的member元素將被忽略。smembers <key>
取出該集合的所有值。sismember <key> <value>
判斷集合<key>是否為含有該<value>值,有則為1,無則0。scard <key>
返回該集合的元素個數(shù)。srem <key> <value1> <value2> ...
刪除集合中的某個元素。spop <key>
隨機從該集合中取出一個值,并刪除。srandmember <key> <n>
隨機從該集合中取出n個值。不會從集合中刪除。smove <source> <destination> value
把集合中一個值從一個集合移動到另一個集合。sinter <key1> <key2>
返回兩個集合的交集。sunion <key1> <key2>
返回兩個集合的并集。sdiff <key1> <key2>
返回兩個集合的差集(key1中的,不包含key2中的)。
數(shù)據(jù)結(jié)構(gòu)
Set 數(shù)據(jù)結(jié)構(gòu)是dict字典,字典使用哈希表實現(xiàn)的。
Java中 HashSet 的內(nèi)部實現(xiàn)使用的是 HashMap,只不過所有的 value 都指向同一個對象。
Redis的 set 結(jié)構(gòu)也是一樣,它的內(nèi)部也使用 hash 結(jié)構(gòu),所有的 value 都指向同一個內(nèi)部值。
Hash
簡介
Redis Hash是一個鍵值對集合。
Redis Hash 是一個string類型的 field 和 value 的映射表,hash 特別適合用于存儲對象。
類似 Java 里面的Map<String,Object>
用戶ID為查找的 Key,存儲的 value 用戶對象包含姓名,年齡,生日等信息,如果用普通的 key/value 結(jié)構(gòu)來存儲,主要有以下2種存儲方式:
- 每次修改用戶的某個屬性,先反序列化改好后再序列化回去,開銷較大。
- 通過
key(用戶ID)+field(屬性標(biāo)簽)
就可以操作對應(yīng)屬性數(shù)據(jù)了,既不需要重復(fù)存儲數(shù)據(jù),也不會帶來序列化和并發(fā)修改控制的問題。
常用命令
hset <key> <field> <value>
給<key>集合種的<field>鍵賦值<value>。hget <key1> <field>
從<key1>集合<field>取出 value。hmset <key1> <field1> <value1> <field2> <value2>...
批量設(shè)置 hash 的值。hexists <key1> <field>
查看哈希表 key 中,給定域 field 是否存在。hkeys <key>
列出該 hash 集合的所有 field。hvals <key>
列出該 hash 集合的所有 value。hincrby <key> <field> <increment>
為哈希表 key 中的域 field的值加上增量 1 -1。hsetnx <key> <field> <value>
將哈希表 key 中的域 field 的值設(shè)置為value,當(dāng)且僅當(dāng)域 field 不存在。
數(shù)據(jù)結(jié)構(gòu)
Hash類型對應(yīng)的數(shù)據(jù)結(jié)構(gòu)是兩種:ziplist(壓縮列表),hashtable(哈希表)。當(dāng) field-value 長度較短且個數(shù)較少時,使用ziplist,否則使用hashtable。
ZSet有序集合(sorted set)
簡介
Redis有序集合 zset 與普通集合 set 非常相似,是一個沒有重復(fù)元素的字符串集合。
不同之處是有序集合的每個成員都關(guān)聯(lián)了一個評分(score)
,這個評分(score)被用來按照最低分到最高分的方式排序集合中的成員。集合的成員是唯一的,但是評分可以是重復(fù)的
。
因為元素是有序的,所以可以很快的根據(jù)評分(score)或者次序(position)來獲取一個范圍的元素。
訪問有序集合的中間元素也是非常快的,因此你能夠使用有序集合作為一個沒有重復(fù)成員的智能列表。
常用命令
zadd <key> <score1> <value1> <score2> <value2>...
將一個或多個member元素及其score值加入到有序集合key當(dāng)中。zrange <key> <start> <stop> [WITHSCORES]
返回有序集key中,下標(biāo)在<strat> <stop>之間的元素。帶WITHSCORES,可以讓分?jǐn)?shù)一起和值返回到結(jié)果集。zrangebyscore key min max [withscores] [limit offset count]
返回有序集key中,所有score值介于min和max之間(包括等于min或max)的成員,有序集成員按score值遞增(從小到大)次序排列。zrevrangebyscore key min max [withscores] [limit offset count]
同上,改為從大到小排列。zincrby <key> <increment> <value>
為元素的score加上增量。zrem <key> <value>
刪除該集合下,指定值的元素。zcount <key> <min> <max>
統(tǒng)計該集合,分?jǐn)?shù)區(qū)間內(nèi)的元素個數(shù)。zrank <key> <value>
返回該值在集合中的排名,從0開始。
數(shù)據(jù)結(jié)構(gòu)
Sorted Set(zset) 是Redis提供的一個非常特別的數(shù)據(jù)結(jié)構(gòu),一方面它等價于Java的數(shù)據(jù)結(jié)構(gòu)Map<String,Double>,可以給每一個元素value賦予一個權(quán)重score,另一方面它又類似于TreeSet,內(nèi)部元素會按照權(quán)重score進行排序,可以得到每個元素的名詞,還可以通過score的范圍來獲取元素的列表。
zset底層使用了兩個數(shù)據(jù)結(jié)構(gòu)。
(1) hash,hash的作用就是關(guān)聯(lián)元素value和權(quán)重score,保障元素value的唯一性,可以通過元素value找到相應(yīng)的score值。
(2) 跳躍表,跳躍表的目的在于給元素value排序,根據(jù)score的范圍獲取元素列表。
跳躍表(跳表)
簡介
有序集合在生活中比較常見,例如根據(jù)成績對學(xué)生排名,根據(jù)得分對玩家排名等。對于有序集合的底層實現(xiàn),可以用數(shù)組、平衡樹、鏈表等。數(shù)組不便元素的插入、刪除;平衡樹或紅黑樹雖然效率搞但結(jié)構(gòu)復(fù)雜;鏈表查詢需要遍歷所有,效率低。Redis采用的是跳躍表。跳躍表效率堪比紅黑樹,實現(xiàn)遠(yuǎn)比紅黑樹簡單。
實例
對比有序鏈表和跳躍表,從鏈表種查詢出51
(1)有序鏈表
要查找值為51的元素,需要從第一個元素開始一次查找、比較才能找到。共需要6次比較。
(2)跳躍表
從第2層開始,1節(jié)點比51節(jié)點小,向后比較。
21節(jié)點比51節(jié)點小,繼續(xù)向后比較,后面就是null了,所以從21節(jié)點向下到第1層。
在第1層,41節(jié)點比51節(jié)點小,繼續(xù)向后,61節(jié)點比51節(jié)點大,所以從41向下。
在第0層,51節(jié)點為要查找的節(jié)點,節(jié)點被找到,共查找4次。
從此可以看出跳躍表比有序鏈表效率要高。
原文鏈接:https://blog.csdn.net/weixin_43712786/article/details/127785561
相關(guān)推薦
- 2022-09-24 Golang?斷言與閉包使用解析_Golang
- 2022-07-08 C語言算法學(xué)習(xí)之雙向鏈表詳解_C 語言
- 2022-06-23 Python在畫圖時使用特殊符號的方法總結(jié)_python
- 2023-07-07 關(guān)于啟動報錯ModuleNotFoundError:No module named ‘python-
- 2022-04-20 Django學(xué)習(xí)之路之請求與響應(yīng)_python
- 2023-01-08 C#?Winform文本面板帶滾動條的實現(xiàn)過程_C#教程
- 2022-05-28 Oracle數(shù)據(jù)庫中通用的函數(shù)實例詳解_oracle
- 2022-07-22 YOLOV7:AttributeError: module ‘distutils‘ has no a
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支