本篇文章給大家整理分享一些常見redis數據結構,還有一些常用指令整理,希望對大家有所幫助!
什么是數據結構?
有Java基礎的應該知道常用的一些數據結構,比如數組、隊列、棧等等… 那redis的數據結構跟Java的數據結構有什么區別嗎?答案是有的,如果一些小伙伴了解的Map的話就知道Map中有一個Key值和一個Value值,Redis的數據結構也是這樣的。
Redis的數據結構:String、List、Hash、Set的話都是有一個Key值和一個Value值。
Key值是名字,Value值就是數據。這兩個是綁定在一起的,一個Key值對應一個Value值,我們稱之這樣的為鍵值對。【相關推薦:Redis視頻教程】
Redis常用的基本命令
在Redis中,在不同的場景下會使用不同的命令。但是不是每個命令都需要記住呢?不是的,只需要熟悉最常用的命令就好了,在需要使用一些少用的命令可以去官方文檔查閱即可。下面來介紹Redis中一些常用的命令。
1.#?exists(判斷key值是否存在):如果存在返回1,反之返回0 ??例子:?exists?name(name為key) 2.#?del(刪除key):?刪除成功返回1,反之返回0 3.#?type(判斷key的類型) 4.ttl(查看key存活時間
想學習更多命令可以自行到中文文檔進行查詢:http://www.redis.cn/
String類型的介紹與使用場景
String字符串類型是Redis中最基本的數據類型,在Redis中的應用場景很廣,一個key對應一個value。
Redis的String是動態字符串,可修改的字符串,它的內部結構類似于Java的ArrayList,采用預分配冗余空間的方式來減少內存的分配。
String類型是二進制安全的,意思就是Redis的String可以包含任何的數據。如:數字,字符串,圖片等
String類型的應用場景:驗證碼、計數器、訂單重復提交、用戶登錄信息、商品詳情的實現
String的常用命令
1.#?set/get?設置和獲取key-value?注意中間一定要加空格 ??例子:?set?xxx(key)?xxx(value)? ?????????get?xxx(key) ????????? 2.#?mget/mset?批量設置或獲取多個key的值 ?????mset?user:name?jack?user:age?2 ?????mget?user:name?user:age ????? 3.#?incr?incr對key對應的值進行加1操作,并返回新的值 ????incr?video:uv:1? ????? 4.?#?incrby?將key對應的數字加increment.如果key不存在,操作之前,key就會被置為0 ????incrby?video:uv:1?10 ???? 5.#?setex?設置key對應字符串value,并且設置key在給定的seconds時間之后超時過期操作 ????setex?code?20?778899?(設置一個key為code?value為778899?20秒后過期)4 6.?#?setnx?將key設置值為value,如果存在該key那么什么都不做,如果不存在key那么等同于set命令 ???setnx?name?xdclass.net ? 7.?#?getset?設置key的值,并返回key舊的值 ????get?name?uuuuu?(這時會返回xdclass.net,重新在get一下會獲得重新設置的值uuuuu)
注意: 值的長度不能超過512MB,遵循key的命名規范:業務名:表明:ID(不要過長,用冒號分割)
String的內部結構(內部結構為深入探究)
Redis中沒有使用C語言的傳統字符串來表示,而是構建了一種名為簡單動態字符串(SDS)的抽象類型。為什么Redis要用自己構建的SDS而不是直接用C語言的String呢?原因其實很簡單,就是為了提升Redis操作的性能。
SDS字符串與C語言字符串具有什么優勢?
-
常數復雜度獲取字符串長度:C語言想獲取長度,那么它必須要遍歷一整個字符串才行。SDS通過len屬性獲取SDS字符串長度的時間復雜度從O(N)變成了O(1),保證了獲取字符串長度時不會成為Redis的性能瓶頸。
-
減少修改帶來的內存重新分配次數:內存重分配就是說在修改字符串時,由于內存空間的不足或者是超出了,需要對執行內存的重分配操作,這種操作由于會涉及到內存,所以導致時間的成本高,所以我們應該盡量的避免內存重分配。而在SDS就是有len和free這兩個屬性,可以使用優化策略來減少對內存重分配次數。
List類型的介紹與使用場景
List類型說白了就是一個鏈表 , 插入元素進去后是有序排列的,value值是可以重復的,可以通過對應的下標獲取對應的value值,鏈表的左右兩邊都能進行插入和刪除數據。在插入時,如果該鍵并不存在,那么Redis將為該鍵創建一個新的鏈表。與此相反,如果這個鏈表中的所有元素都被刪除,那么該鍵也會被刪除掉。
應用場景:簡單隊列、最新評論列表、非實時排行榜:定時計算榜單,如手機日銷榜單
List的常用命令
1.?#?lpush?將一個或多個值插入到列表頭部 ?????lpush?phone:rank:daily?iphone6 ????? 2.?#?rpop?移除并獲取列表的最后一個元素 ?????rpor?phone:rank:daily? 3.?#?llen?獲取列表長度 ?????llen?phone:rank:daily ????? 4.?#?lrange?獲取key對應的list的指定下標范圍元素,其中0表示列表的第一個元素,-1表示獲取列表的所有元素????? ?????lrange?phone:rank:daily?0?-1 ????? 5.?#?rpush?在key對應的list尾部添加一個元素 ?????rpush?phone:rank:daily?xiaodi? 6.?#?lpop?從key對應的List的尾部刪除一個元素,并返回該元素 ?????lpop?phone:rank:daily ????? 7.?#?bropo?移出并獲取列表的最后一個元素,如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止???? ?????brpop?phone:rank:daily?20 ????? 8.?#?lrem?移除元素 ?????lrem?phone:rank:daily?2?a
List的內部結構(內部結構為深入探究)
上面了解了List的常用命令的使用,我們現在就來看下list的底層結構。
List有兩種實現方式
-
壓縮鏈表(ziplist):是Redis為了節省內存空間而開發的,它是特殊編碼的連續內存塊而組成的一個順序數據結構,一個壓縮列表 可以包含許多任意的節點,它的重點是內存連續!
-
雙端鏈表:使用prev和next這兩個指針,是可以從前向后也可以從后向前來實現lpush和rpush這些指令。因為是鏈表,所以也導致了lindex指令獲取某個元素需要遍歷鏈表才能獲取得到。時間復雜度O(n)。
? ? ?當列表的對象同時滿足下述兩個條件時,列表對象采用壓縮鏈表編碼:
? ? (1)列表對象保存的所有元素長度都小于64個字節;
? ? (2)列表元素所保存的元素個數小于512個
在Redis3.2之后,采用的是快速鏈表-quicklist。quicklist是一個雙向鏈表,并且它還是一個有ziplist特性的雙向鏈表,就是說quicklist每個節點都是ziplist。這個快速鏈表結合了兩者的優點。
Hash類型的介紹與使用場景
Redis中的Hash類型是一個String類型的field和value的映射表,Hash特別適合用于存儲對象,Hash類似于Map結構。因為在Redis里,Hash又是另外的一種鍵值對結構,而Redis本身就是key-value類型,所以這個Hash結構是套在了Redis下的value里。
下面說說Hash的底層數據結構:
一種是ziplist , 當存儲的數據超過所配置的數量大小時就是轉成Hashtable這種結構。這種轉換會比較消耗性能,所以盡量少用這種轉換操作。
另一種就是hashtable , 這種結構的時間復雜度為O(1),但是會比較消耗內存空間。 ?
對于Hash在Redis中的應用場景:購物車、用戶個人信息、商品詳情的實現
Hash的常用命令
1.?#?hset?設置key指定的哈希集指定字段的值 ?????hset?product:detail:1?title?iphone11 ????? 2.?#?hget?返回key指定的哈希集中該字段所關聯的值 ?????hget?product:detail:1?title 3.?#?hgetall?返回key指定的哈希集中所有的字段和值 ?????hegetall?product:detail:1 ????? 4.?#?hdel?從key指定的哈希集中移除指定的域????? ?????hdel?product:detail:1?title ????? 5.?#?hexists?返回hash里面的field是否存在 ????hexists?product:detail:1?title??(存在返回1,不存在返回0) 6.?#?hincrby?增加key指定的哈希集中的指定字段的數值,如果是-1則是遞減 ?????hincrby?product:detail:1?key?1?(對key里的value值進行遞增或遞減) ????? 7.?#?hmset?設置key指定的哈希集中指定字段的值???? ?????hmset?product:detail:2?title?xiaomi?price?1000?stock?10 ????? 8.?#?hmget?返回key指定的哈希集中指定字段的值 ?????hmget?product:detail:2?title?price
注意: 每個Hash可以存儲232-1鍵值對
Set類型的介紹與使用場景
Redis中的Set類型是一個集合,集合的概念是一堆不重復的組合。利用Redis提供的Set數據結構可以存儲一些集合性的數據。因為Redis很友好的為集合提供了求集、并集、差集等操作( PS:不懂的同學可以問下以前的數學老師哦~哈哈哈哈),那么就可以非常方便的實現共同關注、共同喜好等功能。對上面的集合操作,你還可以使用不同的命令選擇獎結果返回給客戶端還是存集合到一個新的集合中。
Redis中Set應用場景:去重、社交應用關注(粉絲,共同好友)、統計網站PV(UV、IP)大數據里面的用戶畫像標簽集合
Set的常用命令
1.?#?sadd?添加一個或多個指定的元素到集合中,如果指定的元素已經在集合key中則忽略 ?????sadd?user:tags?female ?????sadd?user:tags?bmw ????? 2.?#?scard?返回集合存儲的key的基數(集合元素的數量) ?????scard?user:tags 3.?#?sdiff?返回的集合元素是第一個key集合與后面所有key集合的差集 ?????sdiff?user:tags:1?user:tags:2 ????? 4.?#?sinter?返回指定所有的集合的成員的交集???? ?????sinter?user:tags:1?user:tags:2 ????? 5.?#?sismember?返回成員是否有存儲的集合key的成員 ????sismember?user:tags:1?bmw?? 6.?#?srem?在集合中移除指定的元素,如果指定元素不是key集合中的則忽略 ?????srem?user:tags:1?bmw? ????? 7.?#?sunion?返回給定的多個集合的并集所有的成員??? ?????sunion?user:tags:1?user:tags:2
SortedSet類型的介紹與使用場景
和Set相比,SortedSet是將Set中的元素增加了一個權重參數score,使得集合中的元素能夠按 score進行有序排序,比如存儲一個存儲班上同學成績的SortedSet集合,該集合value可以設為同學的學號,然而score就可以是考試成績。這樣才插入數據的時候,就已經為數據進行了排序。另外,SortedSet還可以用來做帶權重的隊列。
應用場景:實時排行榜、優先級任務(隊列)、朋友圈(文章)點贊-取消
SortedSet中跳躍表的介紹
跳躍表實則是一個鏈表,在傳統的鏈表中想要查找一個元素就要從最原始的地方開始查找,直到查找到該元素。在跳躍表中呢,它會把鏈表進行抽層,抽層的時候會隔幾個元素分為一個節點,抽層之后也是一條鏈表,節點會變少了。如下圖所示,當要尋找元素78時,如果是尋常的鏈表就會從左往右挨個查詢,這時查詢了8次才能找帶該元素。當使用跳躍表后,從第二層的開始出發,當查詢到79這個節點時發現沒有78,則返回到57這個節點再返回第一層去尋找該元素。
SortedSet的常用命令
1.#?zadd?向有序集合里添加一個或者多個成員,或者更新已存在成員的分數 ????zadd?video:rank?90?springcloud ????zadd?video:rank?80?springboot ????zadd?video:rank?50?redis ???? ?2.#?zcard?獲取有序集合的成員數 ????zcard?video:rank ???? ?3.#?zcount?計算在有序集合中指定的區間分數的成員數 ?????zcount?video:rank?0?60 ? ?4.#?zincrby?在有序集合中對指定成員的分數加上增量 ?????zincrby?video:rank?2?springcloud ? ?5.#?zrange?通過索引區間返回有序集合指定內的成員,成員位置分數按(從小到大排序) ?????zrange?voideo:rank?0?-1? ?????zrange?voideo:rank?0?-1??withscores(返回分數) ? ?6.#?zrevrange?通過索引集合中指定成員的排名,其中有序集合成員按score值遞增(從大到小排序) ?????zrevrange?voideo:rank?0?-1? ? ?7.#?zrevrank?返回有序集合中指定的成員排名,有序集合成員按分數遞減(從大到小排序) ?????zrevrank?voideo:rank?springcloud? ? ?8.#?zrank?返回有序集key中成員member的排名,其中有序集成員按score值遞增(從小到大排序) ?????zrank?voideo:rank ? ?9.#?zrem?移除有序集合中的一個或者多個成員 ??????zrem?voideo:rank?redis ? ?10.#?zscore?返回有序集合中的成員分數值 ?????zscore?voideo:rank?springcloud
好啦Redis的數據類型都整理好了,如果文章對你有幫助的話記得點點贊哈,可以的話也點點關注哦。求求各位大哥啦。
更多編程相關知識,請訪問:Redis視頻教程!!