Ⅰ Redis有哪些數據結構
Redis有五種結構:
1、String
可以是字元串,整數或者
浮點數
,對整個字元串或者字元串中的一部分執行操作,對整個整數或者浮點執行自增(increment)或者自減(decrement)操作。
字元串命令:
①get、獲取存儲在指定鍵中的值
②set、設置存儲在指定鍵中的值
③del、刪除存儲在指定鍵中的值(這個命令可以用於所有的類型)
2、list
一個
鏈表
,鏈表上的每個節點都包含了一個字元串,蟲鏈表的兩端推入或者彈出元素,根據
偏移量
對鏈表進行修剪(trim),讀取單個或者多個元素,根據值查找或者移除元素。
列表命令:
①rpush、將給定值推入列表的右端
②lrange、獲取列表在指定范圍上的所有值
③lindex、獲取列表在指定范圍上的單個元素
④lpop、從列表的左端彈出一個值,並返回被彈出的值
3、set
包含字元串的無序收集器(unordered
collection)、並且被包含的每個字元串都是
獨一無二的
。添加,獲取,移除單個元素,檢查一個元素是否存在於集合中,計算交集,並集,
差集
,從集合裡面隨機獲取元素。
集合命令:
①sadd、將給定元素添加到集合
②smembers、返回集合包含的所有元素
③sismember、檢查指定元素是否存在於集合中
④srem、檢查指定元素是否存在於集合中,那麼移除這個元素
4、hash
包含鍵值對無序
散列
表,添加,獲取,移除當鍵值對,獲取所有鍵值對。
散列命令:
①hset、在散列裡面關聯起指定的鍵值對
②hget、獲取指定散列鍵的值
③hgetall、獲取散列包含的所有鍵值對
④hdel、如果給定鍵存在於散列裡面,那麼移除這個鍵
5、zset
字元串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值的大小決定。添加,獲取,刪除單個元素,根據分值范圍(range)或者成員來獲取元素。
有序集合
命令:
①zadd、將一個帶有給定分值的成員添加到有序集合裡面
②zrange、根據元素在有序排列中所處的位置,從有序集合裡面獲取多個元素
③zrangebyscore、獲取有序集合在給定分值范圍內的所有元素
④zrem、如果指定成員存在於有序集合中,那麼移除這個成員
Ⅱ Redis和關系型資料庫的主要區別,體現在哪些方面
Redis 和關系型資料庫的主要區別有以下幾嫌悄物個方面:
數據存儲方式不同:Redis是基於內存的資料庫,而關系型資料庫通常是基於磁碟的。Redis的數據存儲在內存中,因此讀寫速度非常快,但是容量受到內存大小的限制;而關系型資料庫通常將數據存儲在磁碟運搜中,因此讀寫速度較慢,但是容量可以擴展到很大。
數據結構不同:Redis支持多種數據結構,如字元串、哈希表、列表、集合和有序集合等;而關系型資料庫通常只支持表格結構。
資料庫應用場景不同:Redis主要用於緩存、隊列、計數器等,而關系型資料庫主要用於存儲關系型數據。
資料庫的處理方式不同:Redis可以對數芹液據進行持久化,包括RDB快照和AOF日誌兩種方式,保證數據不丟失。而關系型資料庫通常採用事務機制來保證數據的一致性和完整性。
資料庫的性能不同:Redis的讀寫性能非常高,因為它使用的是內存存儲,而且支持多種數據結構;而關系型資料庫的讀寫性能相對較低,因為它需要通過磁碟進行數據讀寫,並且數據結構比較單一。
總之,Redis和關系型資料庫各有優缺點,應根據應用場景的需求選擇適合的資料庫。
Ⅲ Redis --- 八種數據類型(基本命令)
String、Hash、List、Set和Zset。
等同於java中的, Map<String,String> string 是redis裡面的最基本的數據類型,一個key對應一個value。
應用場景 :String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類,如用戶信息,登錄信息和配置信息等;
實現方式 :String在redis內部存儲默認就是一個字元串,被redisObject所引用,當遇到incr、decr等操作(自增自減等原子操作)時會轉成數值型進行計算,此時redisObject的encoding欄位為int。
Redis雖然是用C語言寫的,但卻沒有直接用C語言的字元串,而是自己實現了一套字元串。目的就是為了提升速度,提升性能。 Redis構建了一個叫做簡單動態字元串(Simple Dynamic String),簡稱SDS。
Redis的字元串也會遵守C語言的字元串的實現規則,即 最後一個字元為空字元。然而這個空並搭字元不會被計算在len里頭。
Redis動態擴展步驟:
Redis字元串的性能優勢
常用命令 :set/get/decr/incr/mget等,具體如下;
ps:計數器(字元串的內容為整數的時候可以使用),如 set number 1。
補充:
等同於java中的: Map<String,Map<String,String>> ,redis的hash是一個string類型的field和value的映射表, 特別適合存儲對象。 在redis中,hash因為是一個集合,所以有兩層。第一層是key:hash集合value,第二層是hashkey:string value。所以判斷是否採用hash的時候可以參照有兩層key的設計來做參考。並且注意的是, 設置過期時間只能在第一層的key上面設置。
應用場景 :我們要存儲一個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日枝旅;
實現方式 :Redis的Hash實際是內部存儲的Value為一個HashMap,並提供了直接存取這個Map成員的介面。如,Key是用戶ID, value是一個Map。 這個Map的key是成員的屬性名,value是屬性值 。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis里稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應屬性數據。 當前HashMap的實現有兩種方式 :當HashMap的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成猛蔽凳真正的HashMap,此時redisObject的encoding欄位為int。
常用命令 :hget/hset/hgetall等,具體如下:
等同於java中的 Map<String,List<String>> ,list 底層是一個鏈表,在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash一樣插入兩層的key。 list是一種有序的、可重復的集合。
應用場景 :Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現;
實現方式 :Redis list的實現為一個 雙向鏈表 ,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括 發送緩沖隊列 等也都是用的這個數據結構。
常用命令 :lpush/rpush/lpop/rpop/lrange等,具體如下:
性能總結 :
它是一個字元串鏈表,left、right都可以插入添加。
等同於java中的 Map<String,Set<String>> ,Set 是一種無序的,不能重復的集合。並且在redis中,只有一個key它的底層由hashTable實現的,天生去重。
應用場景 :Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動去重的,當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且 set提供了判斷某個成員是否在一個set集合內的重要介面 ,這個也是list所不能提供的;如保存一些標簽的名字。標簽的名字不可以重復,順序是可以無序的。
實現方式 :set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。
常用命令 :sadd/spop/smembers/sunion等,具體如下:
ZSet(Sorted Set:有序集合) 每個元素都會關聯一個double類型的分數score,分數允許重復,集合元素按照score排序( 當score相同的時候,會按照被插入的鍵的字典順序進行排序 ),還可以通過 score 的范圍來獲取元素的列表。
應用場景 :Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以 通過用戶額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。 當你需要一個有序的並且不重復的集合列表,那麼可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。
底層實現 : zset 是 Redis 提供的一個非常特別的數據結構,常用作排行榜等功能,以用戶 id 為 value ,關注時間或者分數作為 score 進行排序。實現機制分別是 zipList 和 skipList 。規則如下:
zipList:滿足以下兩個條件
skipList:不滿足以上兩個條件時使用跳錶、組合了hash和skipList
為什麼用skiplist不用平衡樹?
主要從內存佔用、對范圍查找的支持和實現難易程度這三方面總結的原因。
拓展:mysql為什麼不用跳錶?
常用命令 :zadd/zrange/zrem/zcard等;
官網地址: https://redis.io/commands/geoadd
可以用來推算兩地之間的距離,方圓半徑內的人。
關於經度緯度的限制: https://www.redis.net.cn/order/3685.html
一般我們使用Hyperloglog做基數統計。
什麼是基數?就是一個集合中不重復的數的個數。
集合A:{1,3,5,7,9,7}
集合B:{1,3,5,7,9}
AB集合的基數都是5
應用:統計網站的訪問量(一個人訪問網站很多次仍然算作一次)。
優點:佔用的內存是固定的,找2^64次方個數的基數,只需要12KB內存。
缺點:有0.81%的錯誤率,可以忽略不計
概述: bitmap 存儲的是連續的二進制數字(0 和 1),通過 bitmap, 只需要一個 bit 位來表示某個元素對應的值或者狀態,key 就是對應元素本身 。 我們知道 8 個 bit 可以組成一個 byte,所以 bitmap 本身會極大的節省儲存空間。
應用場景: 適合需要保存狀態信息(比如是否簽到、是否登錄...)並需要進一步對這些信息進行分析的場景。比如用戶簽到情況、活躍用戶情況、用戶行為統計(比如是否點贊過某個視頻)。
針對上面提到的一些場景,這里進行進一步說明。
使用場景一:用戶行為分析 很多網站為了分析你的喜好,需要研究你點贊過的內容。
使用場景二:統計活躍用戶
使用時間作為 key,然後用戶 ID 為 offset,如果當日活躍過就設置為 1
那麼我該如果計算某幾天/月/年的活躍用戶呢(暫且約定,統計時間內只有有一天在線就稱為活躍),有請下一個 redis 的命令
使用場景三:用戶在線狀態
對於獲取或者統計用戶在線狀態,使用 bitmap 是一個節約空間效率又高的一種方法。
只需要一個 key,然後用戶 ID 為 offset,如果在線就設置為 1,不在線就設置為 0。
補充 :
巨人的肩膀:
https://www.cnblogs.com/Small-sunshine/p/11687809.html
https://mp.weixin.qq.com/s/CMu7oXVIKp2s-PXTdMlimA