Redis學習筆記二
一、BitMap是什么
就是通過一個bit位來表示某個元素對應的值或者狀態,其中的key就是對應元素本身。我們知道8個bit可以組成一個Byte,所以bitmap本身會極大的節省儲存空間。
二、BitMap算法基本描述
BitMap 是使用 bit位來標記某個元素對應的value,而key 即是該元素,因此對於之前位數存儲換成bit位存儲數據能大大的節省存儲空間。
三、BitMap的實現思想
假設我們要對於0-7內的5個元素(4,7,2,5,3)進行排序(假設元素沒有重復),我們可以利用bitmap達到該目的,要表示8個數,我們需要8bit,每個bit相當於一個標志位,我們可以通過標志位(0,1)去標識本次這個元素是否存在(0,標識不存在;1,標識存在,1Byte=8bit)
首先先開辟1byte的空間,將8個bit位設為0.如這張圖
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
然后遍歷這幾個元素,4為第一個元素,所以把4對應的位置變為1.如下圖
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
接下去遍歷可以得到:
0 |
0 |
1 |
1 |
1 |
1 |
0 |
1 |
然后我們通過GETBIT這個命令可以遍歷bit區域,將標識為1的遍歷出來,得到(2,3,4,5,7)序列,這樣子就得到了排序的結果。
GETBIT key offset
四、BitMap 40億數據處理題目
給你一個文件,里面包含40億個整數,如何利用bitMap思想找出該文件中不包含的一個整數, 假設你有1GB內存可用。
我們用1Byte代替一個整數,那40億數據大概要40*10^8*bit = 0.5GB,滿足內存要求。
用int來表示:Int bmap[1+sum/32]; //N是總數,sum=40*(10^8),一個int=32Bit=4Byte
然后我們插入一個整數ze,要先計算整數ze位於數組Bitmap中的索引:index = ze/32;(除以32是得到整數位於第幾個Byte,也就是第幾位)
比如整數35,index=35/32=1, 35%32=3(取余) 第35位於數組中的index=1(位於數組BitMap[1]中標識等於3的位置),然后就是標識這個位置為1。
知道了這些,我們就可以檢測哪個整數不在數據里面了。
如:檢測35,先計算index,在數組BitMap的標識位置
35: index = 1, 在BitMap[1]中的位置為 1,只需要檢測這個位置是否為1
BitMap[1] &(1<<1),這樣是1返回true,否側返回false
五、Bit-Map的應用
1)可進行數據的快速查找,判重,刪除,一般來說數據范圍是int的10倍以下。
2)去重數據而達到壓縮數據
BitCount
一、bitcount.語法
BitCount:計算key 所儲存的字符串值中,被設置為 1 的比特位的數量。
BITCOUNT key
BITCOUNT key start end |
計算key 所儲存的字符串值中,指定字節區間[start,end]被設置為 1 的比特位的數量。 |
二、使用bitcount統計瀏覽數量
如記錄網站上的用戶的上線頻率,例如計算用戶A上線了多少天,用戶B上線了多少天,以此作為數據,這可以用SETBIT和BITCOUNT來實現。
每當用戶在某一天上線的時候,通過SETBIT命令,以用戶名作為key,將那天所代表的網站的上線日作為offset (標識偏移數)參數,並將這個offset 上的為設置為1。
舉個例子,如果今天是網站上線的第66天,而用戶(user=Y)在今天閱覽過網站,那么執行命令SETBIT person:Y 66 1;如果88號那天用戶(user=Y)也繼續閱覽網站,那么執行命令SETBIT person:Y 88 1,
使用BITCOUNT命令:計算用戶(user=Y)總共上線次數時
執行BITCOUNT person:Y,得出用戶(person=Y)上線的總天數。
三、Python-redis-Bitcount 代碼
import redis r = redis.Redis(host='127.0.0.1', port=6379, db=0) #模擬A用戶 ,一年中 每三天登錄一次。 for i in range(3, 365, 3): r.setbit('ua', i, 1) #模擬B用戶,一年中 每60天登錄一次。 for i in range(1, 365, 60): r.setbit('ub', i, 1) userList = r.keys('u*') #用戶列表 print userList #存放活躍用戶列表 Au = [] #存放非活躍用戶列表 Nau = [] for u in userList : # 計算登錄次數 loginCount = r.bitcount(u) if loginCount > 100 : # 列表添加元組 ()對象 Au.append((u, loginCount)) else : Nau.append((u, loginCount)) for l in Au : print l[0] + ' 是活躍用戶. 登陸' + str(l[1]) + '天' for l in Nau : print l[0] + ' 是非活躍用戶. 登陸' + str(l[1]) + '天' 結果: ['ub', 'ua'] ua 是活躍用戶. 登陸121天 ub 是非活躍用戶. 登陸7天
Bittop命令
處理不同長度的字符串
當 BITOP 處理不同長度的字符串時,較短的那個字符串所缺少的部分會被看作 0 。
空的 key 也被看作是包含 0 的字符串序列