前言
- Redis除了常見的五種數(shù)據(jù)類型之外,其實(shí)還有一些少見的數(shù)據(jù)結(jié)構(gòu),如Geo,HyperLogLog,Bitmap等。雖然它們少見,但是作用卻不容小覷。本文將介紹Bitmap數(shù)據(jù)類型的語法和使用場景。
- 下文將介紹bitmap的使用指令,以及其應(yīng)用場景。
Bitmap概述
- 在開發(fā)中,我們常常需要存放一些布爾類型的數(shù)據(jù),比如我們的上班打卡記錄,游戲簽到記錄等等。假設(shè)一個公司工作簽到打卡的場景,一個員工今年第1,2,3天都工作了,需要對1,2,3做記錄,如果對這三個整型數(shù)使用unsigned int來記錄的話,那么需要3*4=12個字節(jié),也就是96個bit的存儲空間。而一個員工要這樣記錄一整年的數(shù)據(jù),公司又不止一個員工,那么這個打卡功能就將耗費(fèi)大量空間。
- 為了節(jié)省空間,Redis提供了Bitmap,也就是位圖這種數(shù)據(jù)結(jié)構(gòu)。所謂位圖,其實(shí)就是一個bit數(shù)組,對于一年上班打卡的記錄,只需要提供一個365位的bit數(shù)組,如果第一天工作了,那就將第一位bit的0改為1即可。這樣一來,一個人一年的打卡記錄,只需要365bit位就可以記錄完成了。位圖按位來存儲,大大節(jié)約了空間,其存儲上限為2^32。
Bitmap命令介紹
-
bitmap設(shè)置某一位的值: SETBIT key offset value
# 字母a的ASCII碼是97,二進(jìn)制就是01100001,一個字節(jié) 八個比特 # 字母b的ASCII碼是98,二進(jìn)制就是01100010 # 所以存入a只需要將0,6,7位設(shè)為1即可 # 接著存入b就需要將10,14,15位設(shè)為1。 setbit word 0 1 setbit word 6 1 setbit word 7 1 setbit word 10 1 setbit word 14 1 setbit word 15 1 # 除此之外,可以之間用字符串填充位的值 set word ab # 這個指令等價于上面的setbit
-
獲取bitmap中的數(shù)據(jù),使用單個位操作獲取位的值: getbit key offset
getbit word 0 1 getbit word 1 1
-
統(tǒng)計bitmap指定位區(qū)間上,值為 1 的個數(shù): bitcount key [start end]
bitcount word # 統(tǒng)計key為word的位圖中有多少個1 bitcount word 0 1 # 前兩個字符中有幾個1
-
返回bitmap中第一個值為bit的二進(jìn)制位的位置,可以指定范圍: bitpos key bit [start end]
bitpos word 1 # 返回第一個為1的位 bitpos word 0 0 1 # 返回前兩個字符中第一個為0的位
-
對一個或多個保存二進(jìn)制位的字符串 key 進(jìn)行位元操作(and,or,not,xor),并將結(jié)果保存到 destkey 上: BITOP operation destkey key [key …]文章來源:http://www.zghlxwxcb.cn/news/detail-820071.html
bitop not new_word word # 對key為word的位圖取反后存入new_word之中
文章來源地址http://www.zghlxwxcb.cn/news/detail-820071.html
使用場景
- 需求:40億個QQ號,限制1G的內(nèi)存,如何對這些QQ號進(jìn)行去重。
- 實(shí)現(xiàn)方案:通過分析需求,有1G內(nèi)存的限制,所以可以使用位圖來節(jié)省空間。使用位圖的話,一個qq號,即一個數(shù)字只需要占用一個bit(將這個bit設(shè)置為1),那么40億個數(shù)字也就只需要400000000/8/1024/1024=476M,滿足要求。
- 代碼實(shí)現(xiàn):
public class RedisBitmap { private static final String QQ_NUMBER = "QQ"; /** * 將qq號碼存入位圖中 * 即將位圖對應(yīng)qq號碼的bit設(shè)為1 * @param key * @param qq_number * @param jedis */ public static void saveQQNumber(String key, long qq_number, Jedis jedis){ jedis.setbit(key,qq_number,true); } /** * 獲取bitmap中1的數(shù)量即可得到去重后的qq號數(shù)量 * @param key * @param jedis */ public static Long getCount(String key, Jedis jedis){ return jedis.bitcount(key); } }
結(jié)尾
- bitmap常用于上面提及的去重,上班打卡,簽到記錄功能,使用bitmap可以減少很多不必要的存儲空間。所以當(dāng)出現(xiàn)類似的場景時,就好好使用它吧。
到了這里,關(guān)于Redis--Bitmap有序集合的語法和使用場景舉例的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!