Redis --- 八種數(shù)據(jù)類型(基本命令)

五種基本數(shù)據(jù)類型

String、Hash、List、Set和Zset。

1、String

等同于java中的,Map<String,String>string 是redis里面的最基本的數(shù)據(jù)類型,一個(gè)key對(duì)應(yīng)一個(gè)value。

  • string 是二進(jìn)制安全的,可以把圖片和視頻文件保存在String中。
  • string的最大內(nèi)存值 512M,即一個(gè)key或者value最大值是512M,官方說(shuō)可以存2.5億個(gè)key。

應(yīng)用場(chǎng)景:String是最常用的一種數(shù)據(jù)類型,普通的key/value存儲(chǔ)都可以歸為此類,如用戶信息,登錄信息和配置信息等;

實(shí)現(xiàn)方式:String在redis內(nèi)部存儲(chǔ)默認(rèn)就是一個(gè)字符串,被redisObject所引用,當(dāng)遇到incr、decr等操作(自增自減等原子操作)時(shí)會(huì)轉(zhuǎn)成數(shù)值型進(jìn)行計(jì)算,此時(shí)redisObject的encoding字段為int。

Redis雖然是用C語(yǔ)言寫的,但卻沒(méi)有直接用C語(yǔ)言的字符串,而是自己實(shí)現(xiàn)了一套字符串。目的就是為了提升速度,提升性能。Redis構(gòu)建了一個(gè)叫做簡(jiǎn)單動(dòng)態(tài)字符串(Simple Dynamic String),簡(jiǎn)稱SDS。

struct sdshdr{    
    //  記錄已使用長(zhǎng)度    
    int len;    
    // 記錄空閑未使用的長(zhǎng)度    
    int free;    
    // 字符數(shù)組    
    char[] buf;    
};  

Redis的字符串也會(huì)遵守C語(yǔ)言的字符串的實(shí)現(xiàn)規(guī)則,即最后一個(gè)字符為空字符。然而這個(gè)空字符不會(huì)被計(jì)算在len里頭。

  • 因?yàn)橛辛藢?duì)字符串長(zhǎng)度定義len, 所以在處理字符串時(shí)候不會(huì)以零值字節(jié)(\0)為字符串結(jié)尾標(biāo)志.
  • 二進(jìn)制安全就是輸入任何字節(jié)都能正確處理, 即使包含零值字節(jié).

Redis動(dòng)態(tài)擴(kuò)展步驟:

  • 計(jì)算出大小是否足夠
  • 開(kāi)辟空間至滿足所需大小
  • 開(kāi)辟與已使用大小len相長(zhǎng)度同的空閑free空間(如果len < 1M),開(kāi)辟1M長(zhǎng)度的空閑free空間(如果len >= 1M)

Redis字符串的性能優(yōu)勢(shì)

  • 快速獲取字符串長(zhǎng)度:直接返回len
  • 避免緩沖區(qū)溢出:每次追加字符串時(shí)都會(huì)檢查空間是否夠用
  • 降低空間分配次數(shù)提升內(nèi)存使用效率:(1)空間預(yù)分配;(2)惰性空間回收

常用命令:set/get/decr/incr/mget等,具體如下;

常用命令 命令
添加一對(duì)kv set key value
添加多對(duì)kv(可覆蓋) mset key value key value….
添加多對(duì)kv(不可覆蓋,只要有一個(gè)已存在,全部取消) msetnx key value key value….
獲取 get value
獲取多對(duì)kv mget key key…
刪除 del key
在末尾追加 append key value
查詢v的長(zhǎng)度 strlen key
給數(shù)值類型的v加/減1 incr/decr key
給數(shù)值類型增加/減少指定大小的值 incrby/decrby key value
獲取v的長(zhǎng)度 getrange key
在指定位置添加指定值(中間默認(rèn)用空格補(bǔ)全) setrange key offset value
添加指定生命周期的kv setex key seconds value
如果不存在則添加 setnx key value
獲取舊值,設(shè)置新值 setget key value

ps:計(jì)數(shù)器(字符串的內(nèi)容為整數(shù)的時(shí)候可以使用),如 set number 1。

補(bǔ)充:

127.0.0.1:6379> expire key  60 # 數(shù)據(jù)在 60s 后過(guò)期
(integer) 1
127.0.0.1:6379> setex key 60 value # 數(shù)據(jù)在 60s 后過(guò)期 (setex:[set] + [ex]pire)
OK
127.0.0.1:6379> ttl key # 查看數(shù)據(jù)還有多久過(guò)期
(integer) 56

2、Hash

等同于java中的:Map<String,Map<String,String>>,redis的hash是一個(gè)string類型的field和value的映射表,特別適合存儲(chǔ)對(duì)象。在redis中,hash因?yàn)槭且粋€(gè)集合,所以有兩層。第一層是key:hash集合value,第二層是hashkey:string value。所以判斷是否采用hash的時(shí)候可以參照有兩層key的設(shè)計(jì)來(lái)做參考。并且注意的是,設(shè)置過(guò)期時(shí)間只能在第一層的key上面設(shè)置。

  • 使用hash,一般是有那種需要兩層key的應(yīng)用場(chǎng)景,也可以是‘刪除一個(gè)key可以刪除所有內(nèi)容’的場(chǎng)景。例如一個(gè)商品有很多規(guī)格,規(guī)格里面有不同的值。
  • 或者查找所有商品的規(guī)格,查找商品id即可,具體的規(guī)格可以通過(guò)兩個(gè)key查找。

應(yīng)用場(chǎng)景:我們要存儲(chǔ)一個(gè)用戶信息對(duì)象數(shù)據(jù),其中包括用戶ID、用戶姓名、年齡和生日,通過(guò)用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;

實(shí)現(xiàn)方式:Redis的Hash實(shí)際是內(nèi)部存儲(chǔ)的Value為一個(gè)HashMap,并提供了直接存取這個(gè)Map成員的接口。如,Key是用戶ID, value是一個(gè)Map。這個(gè)Map的key是成員的屬性名,value是屬性值。這樣對(duì)數(shù)據(jù)的修改和存取都可以直接通過(guò)其內(nèi)部Map的Key(Redis里稱內(nèi)部Map的key為field), 也就是通過(guò) key(用戶ID) + field(屬性標(biāo)簽) 就可以操作對(duì)應(yīng)屬性數(shù)據(jù)。當(dāng)前HashMap的實(shí)現(xiàn)有兩種方式:當(dāng)HashMap的成員比較少時(shí)Redis為了節(jié)省內(nèi)存會(huì)采用類似一維數(shù)組的方式來(lái)緊湊存儲(chǔ),而不會(huì)采用真正的HashMap結(jié)構(gòu),這時(shí)對(duì)應(yīng)的value的redisObject的encoding為zipmap,當(dāng)成員數(shù)量增大時(shí)會(huì)自動(dòng)轉(zhuǎn)成真正的HashMap,此時(shí)redisObject的encoding字段為int。

常用命令:hget/hset/hgetall等,具體如下:

作用 命令
添加單個(gè) hset key field value
獲取單個(gè) hget key field
一次性添加多個(gè)鍵值 hmset key field1 value1 field2 value2 …
一次性獲取多個(gè) hmget
獲取所有鍵值 hgetall key
刪除 hdel
獲取鍵值對(duì)的個(gè)數(shù) hlen
檢查是否包含某個(gè)字段 hget key field
查看所有key hkeys
給某個(gè)數(shù)值類型(否則報(bào)錯(cuò))的值增加指定整數(shù)值 hincrby key field increment
給某個(gè)數(shù)字類型值,增加指定浮點(diǎn)類型值 hincrbyfloat key field increment
如果不存在則添加 hsetnx

3、list

等同于java中的Map<String,List<String>>,list 底層是一個(gè)鏈表,在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash一樣插入兩層的key。list是一種有序的、可重復(fù)的集合。

  • redis的list是一個(gè)雙向鏈表(易于插入和刪除元素)。
  • 它會(huì)按照我們插入的順序排序,然后我們可以從他的頭部添加/獲取元素,也可以從它的尾部添加/獲取元素,但帶來(lái)的額外的空間開(kāi)銷

應(yīng)用場(chǎng)景:Redis list的應(yīng)用場(chǎng)景非常多,也是Redis最重要的數(shù)據(jù)結(jié)構(gòu)之一,比如twitter的關(guān)注列表,粉絲列表等都可以用Redis的list結(jié)構(gòu)來(lái)實(shí)現(xiàn);

實(shí)現(xiàn)方式:Redis list的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過(guò)帶來(lái)了部分額外的內(nèi)存開(kāi)銷,Redis內(nèi)部的很多實(shí)現(xiàn),包括發(fā)送緩沖隊(duì)列等也都是用的這個(gè)數(shù)據(jù)結(jié)構(gòu)。

常用命令:lpush/rpush/lpop/rpop/lrange等,具體如下:

常用命令 命令
左壓棧 lpush key v1 v2 v3 v4…
右壓棧 rpush key v1 v2 …
查看里面的元素 lrange key start offset
左彈棧 lpop key
右彈棧 rpop key
按照索引查找 lindex key index
查看長(zhǎng)度 llen key
刪除幾個(gè)幾 lrem key 數(shù)量 value
指定開(kāi)始和結(jié)束的位置截取,再賦值給key ltrim key start offset
右出棧左壓棧,把resoure的左后一個(gè),壓倒dest的第一個(gè) rpoplpush resource destination
重置指定索引的值 lset key index value
在指定元素前/后插入指定元素 linsert key before/after 值1 值2

性能總結(jié):

它是一個(gè)字符串鏈表,left、right都可以插入添加。

  • 如果鍵不存在,創(chuàng)建新的鏈表。
  • 如果鍵已經(jīng)存在,新增內(nèi)容。
  • 值全部移除,key消失。
  • 由于是鏈表,所以它對(duì)頭和尾操作的效率都極高。但是假如是對(duì)中間元素的操作,效率就可憐了。

4、Set

等同于java中的Map<String,Set<String>>,Set 是一種無(wú)序的,不能重復(fù)的集合。并且在redis中,只有一個(gè)key它的底層由hashTable實(shí)現(xiàn)的,天生去重。

應(yīng)用場(chǎng)景:Redis set對(duì)外提供的功能與list類似是一個(gè)列表的功能,特殊之處在于set是可以自動(dòng)去重的,當(dāng)你需要存儲(chǔ)一個(gè)列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時(shí),set是一個(gè)很好的選擇,并且set提供了判斷某個(gè)成員是否在一個(gè)set集合內(nèi)的重要接口,這個(gè)也是list所不能提供的;如保存一些標(biāo)簽的名字。標(biāo)簽的名字不可以重復(fù),順序是可以無(wú)序的。

實(shí)現(xiàn)方式:set 的內(nèi)部實(shí)現(xiàn)是一個(gè) value永遠(yuǎn)為null的HashMap,實(shí)際就是通過(guò)計(jì)算hash的方式來(lái)快速排重的,這也是set能提供判斷一個(gè)成員是否在集合內(nèi)的原因。

常用命令:sadd/spop/smembers/sunion等,具體如下:

常用命令 命令
添加值 sadd key values
查看值 smembers key
檢查集合是否有值 sismember key value
查看set集合里面的元素個(gè)數(shù) scard key
刪除集合中的指定元素 srem key value
隨機(jī)彈出某個(gè)元素 srandmember key
隨機(jī)出棧 spop key
把key1中的某個(gè)值賦值給key2 smove SourceSet destSet member
數(shù)學(xué)集合類 命令
差集 sdiff
交集 sinte
并集 sunion

5、Zset

ZSet(Sorted Set:有序集合) 每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)score,分?jǐn)?shù)允許重復(fù),集合元素按照score排序(當(dāng)score相同的時(shí)候,會(huì)按照被插入的鍵的字典順序進(jìn)行排序),還可以通過(guò) score 的范圍來(lái)獲取元素的列表。

  • set的值是 k1 v1 k2 v2
  • zset的值 K1 score v1 k2 score v2

應(yīng)用場(chǎng)景:Redis sorted set的使用場(chǎng)景與set類似,區(qū)別是set不是自動(dòng)有序的,而sorted set可以通過(guò)用戶額外提供一個(gè)優(yōu)先級(jí)(score)的參數(shù)來(lái)為成員排序,并且是插入有序的,即自動(dòng)排序。當(dāng)你需要一個(gè)有序的并且不重復(fù)的集合列表,那么可以選擇sorted set數(shù)據(jù)結(jié)構(gòu),比如twitter 的public timeline可以以發(fā)表時(shí)間作為score來(lái)存儲(chǔ),這樣獲取時(shí)就是自動(dòng)按時(shí)間排好序的。

底層實(shí)現(xiàn)zsetRedis提供的一個(gè)非常特別的數(shù)據(jù)結(jié)構(gòu),常用作排行榜等功能,以用戶idvalue,關(guān)注時(shí)間或者分?jǐn)?shù)作為score進(jìn)行排序。實(shí)現(xiàn)機(jī)制分別是zipListskipList。規(guī)則如下:

zipList:滿足以下兩個(gè)條件

  • [score,value]鍵值對(duì)數(shù)量少于128個(gè);
  • 每個(gè)元素的長(zhǎng)度小于64字節(jié);

skipList:不滿足以上兩個(gè)條件時(shí)使用跳表、組合了hash和skipList

  • hash用來(lái)存儲(chǔ)valuescore的映射,這樣就可以在O(1)時(shí)間內(nèi)找到value對(duì)應(yīng)的分?jǐn)?shù);
  • skipList按照從小到大的順序存儲(chǔ)分?jǐn)?shù)
  • skipList每個(gè)元素的值都是[socre,value]對(duì)

為什么用skiplist不用平衡樹(shù)?

主要從內(nèi)存占用、對(duì)范圍查找的支持和實(shí)現(xiàn)難易程度這三方面總結(jié)的原因。

  • 內(nèi)存占用:skiplist比平衡樹(shù)更靈活一些。一般來(lái)說(shuō),平衡樹(shù)每個(gè)節(jié)點(diǎn)至少包含2個(gè)指針,而skiplist每個(gè)節(jié)點(diǎn)包含的指針數(shù)目平均為1/(1-p),具體取決于參數(shù)p的大小。如果像Redis里的實(shí)現(xiàn)一樣,取p=1/4,那么平均每個(gè)節(jié)點(diǎn)包含1.33個(gè)指針,比平衡樹(shù)更有優(yōu)勢(shì)。
  • 范圍查找的支持:在做范圍查找的時(shí)候,平衡樹(shù)比skiplist操作要復(fù)雜。在平衡樹(shù)上,我們找到指定范圍的小值之后,還需要以中序遍歷的順序繼續(xù)尋找其它不超過(guò)大值的節(jié)點(diǎn)。如果不對(duì)平衡樹(shù)進(jìn)行一定的改造,這里的中序遍歷并不容易實(shí)現(xiàn)。而在skiplist上進(jìn)行范圍查找就非常簡(jiǎn)單,只需要在找到小值之后,對(duì)第1層鏈表進(jìn)行若干步的遍歷就可以實(shí)現(xiàn)。
  • 實(shí)現(xiàn)難易程度:skiplist更加簡(jiǎn)單,平衡樹(shù)的插入和刪除操作可能引發(fā)子樹(shù)的調(diào)整,邏輯復(fù)雜,而skiplist的插入和刪除只需要修改相鄰節(jié)點(diǎn)的指針,操作簡(jiǎn)單又快速。

拓展:mysql為什么不用跳表?

常用命令:zadd/zrange/zrem/zcard等;

127.0.0.1:6379> zadd myZset 3.0 value1 # 添加元素到 sorted set 中 3.0 為權(quán)重
(integer) 1
127.0.0.1:6379> zadd myZset 2.0 value2 1.0 value3 # 一次添加多個(gè)元素
(integer) 2
127.0.0.1:6379> zcard myZset # 查看 sorted set 中的元素?cái)?shù)量
(integer) 3
127.0.0.1:6379> zscore myZset value1 # 查看某個(gè) value 的權(quán)重
"3"
127.0.0.1:6379> zrange  myZset 0 -1 # 順序輸出某個(gè)范圍區(qū)間的元素,0 -1 表示輸出所有元素
1) "value3"
2) "value2"
3) "value1"
127.0.0.1:6379> zrange  myZset 0 1 # 順序輸出某個(gè)范圍區(qū)間的元素,0 為 start  1 為 stop
1) "value3"
2) "value2"
127.0.0.1:6379> zrevrange  myZset 0 1 # 逆序輸出某個(gè)范圍區(qū)間的元素,0 為 start  1 為 stop
1) "value1"
2) "value2"

三大特殊數(shù)據(jù)類型

1、geospatial

官網(wǎng)地址:https://redis.io/commands/geoadd

可以用來(lái)推算兩地之間的距離,方圓半徑內(nèi)的人。

關(guān)于經(jīng)度緯度的限制:https://www.redis.net.cn/order/3685.html

 1# 添加三個(gè)城市
 2127.0.0.1:16379[2]> geoadd china:city 116.40  39.99 beijing
 3(integer) 1
 4127.0.0.1:16379[2]> geoadd china:city 117.190 39.1255 tianjin
 5(integer) 1
 6127.0.0.1:16379[2]> geoadd china:city 120.36955 36.094 qingdao
 7(integer) 1
 8127.0.0.1:16379[2]>
 9
10# 獲取指定key的經(jīng)度和緯度
11127.0.0.1:16379[2]> geopos china:city beijing
121) 1) "116.39999896287918091"
13   2) "39.99000043587556519"
14127.0.0.1:16379[2]>
15
16# 獲取兩個(gè)給定位置的距離
17127.0.0.1:16379[2]> geodist china:city beijing qingdao # 默認(rèn)單位為米
18"555465.2188"
19127.0.0.1:16379[2]> geodist china:city beijing qingdao km
20"555.4652"
21127.0.0.1:16379[2]> geodist china:city beijing qingdao m
22"555465.2188"
23127.0.0.1:16379[2]> geodist china:city beijing qingdao mi # 英里
24"345.1509"
25127.0.0.1:16379[2]> geodist china:city beijing qingdao ft # 英尺
26"1822392.4503"
27
28# 查找附近的人
29# 以給定的經(jīng)緯度為中心,找出某一半徑內(nèi)的元素
30127.0.0.1:16379[2]> georadius china:city 117.190 39.1255 200 km # 半徑為200km
311) "tianjin"
322) "beijing"
33127.0.0.1:16379[2]> georadius china:city 117.190 39.1255 200 km withdist # 指定顯示距離
341) 1) "tianjin"
35   2) "0.0001"
362) 1) "beijing"
37   2) "117.6221"
38127.0.0.1:16379[2]> georadius china:city 117.190 39.1255 200 km count 2 # 指定顯示2個(gè)結(jié)果
391) 1) "tianjin"
40   2) "0.0001"
412) 1) "beijing"
42   2) "117.6221"
43
44# 以指定的members為依據(jù),找到它指定范圍內(nèi)的元素
45127.0.0.1:16379[2]> GEORADIUSBYMEMBER china:city beijing 120 km
461) "beijing"
472) "tianjin"
48
49# 返回一個(gè)或者多個(gè)位置的11位長(zhǎng)度的hash串表示
50127.0.0.1:16379[2]> geohash china:city beijing
511) "wx4g2xzyss0"
52127.0.0.1:16379[2]> geohash china:city beijing tianjin
531) "wx4g2xzyss0"
542) "wwgqddx4sc0"
55
56# geo底層使用 zset 實(shí)現(xiàn)
57127.0.0.1:16379[2]> ZRANGE china:city 0 -1
581) "qingdao"
592) "tianjin"
603) "beijing"
61
62# 可以通過(guò)zrem刪除 geo添加的key中的member
63127.0.0.1:16379[2]> ZREM china:city beijing
64(integer) 1
65127.0.0.1:16379[2]> ZRANGE china:city 0 -1
661) "qingdao"
672) "tianjin"

2、Hyperloglog

一般我們使用Hyperloglog做基數(shù)統(tǒng)計(jì)。

什么是基數(shù)?就是一個(gè)集合中不重復(fù)的數(shù)的個(gè)數(shù)。

集合A:{1,3,5,7,9,7}

集合B:{1,3,5,7,9}

AB集合的基數(shù)都是5

應(yīng)用:統(tǒng)計(jì)網(wǎng)站的訪問(wèn)量(一個(gè)人訪問(wèn)網(wǎng)站很多次仍然算作一次)。

優(yōu)點(diǎn):占用的內(nèi)存是固定的,找2^64次方個(gè)數(shù)的基數(shù),只需要12KB內(nèi)存。

缺點(diǎn):有0.81%的錯(cuò)誤率,可以忽略不計(jì)

 1# PFCOUNT 計(jì)算出來(lái)的數(shù)量就是Set的基數(shù)
 2127.0.0.1:16379[2]> PFADD key4 q w e r q
 3(integer) 1
 4127.0.0.1:16379[2]> PFCOUNT key4
 5(integer) 4
 6
 7# 添加key1和key對(duì)應(yīng)的多個(gè)值
 8127.0.0.1:16379[2]> PFADD key1 q w e r
 9(integer) 1
10
11# 統(tǒng)計(jì)key下有多少個(gè)值
12127.0.0.1:16379[2]> PFCOUNT key1
13(integer) 4
14
15# 添加key2和key對(duì)應(yīng)的多個(gè)值
16127.0.0.1:16379[2]> PFADD key2 a s d f
17(integer) 1
18
19# 合并多個(gè)key成為一個(gè)key
20127.0.0.1:16379[2]> PFMERGE key3 key1 key2
21OK
22127.0.0.1:16379[2]> PFCOUNT key3
23(integer) 8

3、Bitmap(*)

概述:bitmap 存儲(chǔ)的是連續(xù)的二進(jìn)制數(shù)字(0 和 1),通過(guò) bitmap, 只需要一個(gè) bit 位來(lái)表示某個(gè)元素對(duì)應(yīng)的值或者狀態(tài),key 就是對(duì)應(yīng)元素本身 。我們知道 8 個(gè) bit 可以組成一個(gè) byte,所以 bitmap 本身會(huì)極大的節(jié)省儲(chǔ)存空間。

應(yīng)用場(chǎng)景: 適合需要保存狀態(tài)信息(比如是否簽到、是否登錄...)并需要進(jìn)一步對(duì)這些信息進(jìn)行分析的場(chǎng)景。比如用戶簽到情況、活躍用戶情況、用戶行為統(tǒng)計(jì)(比如是否點(diǎn)贊過(guò)某個(gè)視頻)。

針對(duì)上面提到的一些場(chǎng)景,這里進(jìn)行進(jìn)一步說(shuō)明。

使用場(chǎng)景一:用戶行為分析 很多網(wǎng)站為了分析你的喜好,需要研究你點(diǎn)贊過(guò)的內(nèi)容。

# 記錄你喜歡過(guò) 001 號(hào)小姐姐
127.0.0.1:6379> setbit beauty_girl_001 uid 1
Copy to clipboardErrorCopied

使用場(chǎng)景二:統(tǒng)計(jì)活躍用戶

使用時(shí)間作為 key,然后用戶 ID 為 offset,如果當(dāng)日活躍過(guò)就設(shè)置為 1

那么我該如果計(jì)算某幾天/月/年的活躍用戶呢(暫且約定,統(tǒng)計(jì)時(shí)間內(nèi)只有有一天在線就稱為活躍),有請(qǐng)下一個(gè) redis 的命令

# 對(duì)一個(gè)或多個(gè)保存二進(jìn)制位的字符串 key 進(jìn)行位元操作,并將結(jié)果保存到 destkey 上。
# BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 這四種操作中的任意一種參數(shù)
BITOP operation destkey key [key ...]
Copy to clipboardErrorCopied

初始化數(shù)據(jù):

127.0.0.1:6379> setbit 20210308 1 1
(integer) 0
127.0.0.1:6379> setbit 20210308 2 1
(integer) 0
127.0.0.1:6379> setbit 20210309 1 1
(integer) 0
Copy to clipboardErrorCopied

統(tǒng)計(jì) 20210308~20210309 總活躍用戶數(shù): 1

127.0.0.1:6379> bitop and desk1 20210308 20210309
(integer) 1
127.0.0.1:6379> bitcount desk1
(integer) 1
Copy to clipboardErrorCopied

統(tǒng)計(jì) 20210308~20210309 在線活躍用戶數(shù): 2

127.0.0.1:6379> bitop or desk2 20210308 20210309
(integer) 1
127.0.0.1:6379> bitcount desk2
(integer) 2
Copy to clipboardErrorCopied

使用場(chǎng)景三:用戶在線狀態(tài)

對(duì)于獲取或者統(tǒng)計(jì)用戶在線狀態(tài),使用 bitmap 是一個(gè)節(jié)約空間效率又高的一種方法。

只需要一個(gè) key,然后用戶 ID 為 offset,如果在線就設(shè)置為 1,不在線就設(shè)置為 0。

總結(jié)

  • 速度快,因?yàn)?strong>數(shù)據(jù)存在內(nèi)存中,類似于HashMap,HashMap的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是O(1)
  • 支持豐富數(shù)據(jù)類型,支持string,list,set,sorted set(zset),hash

補(bǔ)充

  • 一個(gè)字符串類型的值能存儲(chǔ)最大容量是512M
  • 其余類型元素最大存儲(chǔ)量為2^32 - 1,注意hash是鍵值對(duì)的個(gè)數(shù)

巨人的肩膀:

https://www.cnblogs.com/Small-sunshine/p/11687809.html
https://mp.weixin.qq.com/s/CMu7oXVIKp2s-PXTdMlimA

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容