小編給大家分享一下redis位圖怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)建站長期為1000+客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為澠池企業(yè)提供專業(yè)的成都網(wǎng)站建設、成都網(wǎng)站設計,澠池網(wǎng)站改版等技術(shù)服務。擁有10多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
Redis也有這樣的結(jié)構(gòu)名叫位圖,位圖最小的單位是bit,每個bit是由0或1構(gòu)成,我們的字符串就是由很多個bit數(shù)組組成的,所以我們在使用位圖的時候是可以把一組bit轉(zhuǎn)換成字符串,也可以由字符串轉(zhuǎn)換成bit數(shù)組。
如下,“h”的ACSLL碼是0110 1000
> setbit name 1 1 #設置位圖的位置(integer) 0> setbit name 2 1(integer) 0> setbit name 4 1(integer) 0> get name #獲取這個位圖轉(zhuǎn)換成字符串的值"h"> getbit name 1 #獲取位圖的某個位置是否有值(integer) 1> getbit name 3(integer) 0
字符串轉(zhuǎn)位圖
> set kh h #存字符串OK> getbit kh 1 #第二個位置的bit是1(integer) 1> getbit kh 3 #第四個位置的bit是0(integer) 0
注意:如果對應位的字節(jié)是不可打印字符,redis會顯示該字符的十六進制形式。
> setbit x O 1(integer) 0> setbit x 1 1(integer) 0> get x"\xc0"
Redis位圖提供bitcount和bitpos指令,bitcount用來統(tǒng)計一定范圍內(nèi)1的個數(shù),bitpos用來查找指定范圍內(nèi)出現(xiàn)的第一個0或者1。
這里我們需要注意的是參數(shù)start_index和end_index是字節(jié)索引,簡單的來說就是他們只能是8的倍數(shù)而不是指定值。
咱們對照下圖來看
> set name helloOK127.0.0.1:6379> bitcount name #計數(shù)所有的1的個數(shù)(integer) 21127.0.0.1:6379> bitcount name 0 1 #獲取前兩個字符出現(xiàn)1的個數(shù)(integer) 7127.0.0.1:6379> bitcount name 0 0 #獲取第一個字符出現(xiàn)1的個數(shù)(integer) 3127.0.0.1:6379> bitpos name 1 #獲取第一個1出現(xiàn)的位置(integer) 1127.0.0.1:6379> bitpos name 0 #獲取第一個0出現(xiàn)的位置(integer) 0127.0.0.1:6379> bitpos name 1 1 1 #獲取第二個字符1出現(xiàn)的位置(integer) 9
我們通過setbit和getbit指令來操作位圖都是一次操作一個位,那么有時候我們需要一次性操作多個位,如何操作呢?
在Redis3.2版本之前我們可以使用管道來一次性操作多個指令,redis給我們提供了bitfield指令,該指令有三個子指令分別是get、set、incrby它們都可以對指定位片段進行讀寫,但是最多只能處理64個連續(xù)的位,如果超過64位,就得使用多個子指令,bitfield 可以一次執(zhí)行多個子指令。
下面我們來看例子,還是使用上面的name=hello
字母 | 數(shù)值 | 二進制 |
h | 104 | 0110 1000 |
e | 101 | 0110 0101 |
l | 108 | 0110 1100 |
l | 108 | 0110 1100 |
o | 111 | 0110 1111 |
> bitfield name get u4 0 #第一個位開始取4個位(0110),結(jié)果為無符號數(shù)(u)(integer) 6> bitfield name get u3 2 #第三個位開始取3個位(101),結(jié)果為無符號數(shù)(u)(integer) 5> bitfield name get i4 0 #第一個位開始取4個位(0110),結(jié)果為有符號數(shù)(i)(integer) 6> bitfield name get i3 2 #第三個位開始取3個位(101),結(jié)果為有符號數(shù)(i)(integer) -3
下面我們才試試批處理
> bitfield name get u4 0 get u3 2 get i4 0 get i3 2(integer) 6(integer) 5(integer) 6(integer) -3
有符號數(shù)是指獲取的位數(shù)組中第一個位是符號位,剩下的才是值。如果第一位是1,那就是負數(shù)。無符號數(shù)表示非負數(shù),沒有符號位,獲取的位數(shù)組全部都是值。有符號數(shù)最多可以獲取 64 位,無符號數(shù)只能獲取 63 位(因為 Redis 協(xié)議中的integer是有符號數(shù),最大 64 位,不能傳遞 64 位無符號值)。
下面我們來使用set,把hello的e變成a,a的ASCLL碼是97
>bitfield name set u8 8 97 #從第八位開始,接下來的8位用無符號的ASCLL碼97代替(integer)101 >get name"hallo"
這個指令用來自增,如果自增到最大值的時候會溢出,如果是無符號那么就變成0,如果是有符號的就會變成負數(shù),向下自增反之。
bitfield指令提供溢出策略的指令overflow,用戶可以指定類型,默認為:wrap,溢出及折返,還可以選擇失?。篺ail,失敗不執(zhí)行,截斷:sat,溢出就停留。
> bitfield name incrby u4 2 1 #從第三個位開始,對接下來的4位元符號數(shù)+ 1(integer) 11> bitfield name incrby u4 2 1(integer) 12> bitfield name incrby u4 2 1(integer) 13> bitfield name incrby u4 2 1(integer) 14> bitfield name incrby u4 2 1(integer) 15####sat> bitfield name overflow sat incrby u4 2 1 #保持最大值(integer) 15####fail> bitfield name overflow fail incrby u4 2 1 #不執(zhí)行(nil)####wrap> bitfield name incrby u4 2 1 #溢出折返(integer) 0
以上是“Redis位圖怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!