开发者学堂课程【Redis 数据库入门:Redis_字符串键_BitMap 操作_4】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/15/detail/48
Redis_字符串键_BitMap 操作_4
内容介绍:
一、字符串
一、字符串
bitop 有四种,OR 表示或,key3 表示结果,key1、key2 表示分别对这两个求或。或表示的意思是,0和1,未操作就是1。1就是1,只要未操作就是1。0和0就是0。
得出的结果为:c。所以a是0b01100011,b是0b01100010,求或就是对最后一位进行修改。在print r.get(‘key3’)
变成c。
代码如下:
r
.set(‘key1’,’a’)
r
.set(‘key2’,’b’)
r
.bitop(‘OR’,’key3’,’key1’,’key2’)
p
rint r.get(‘key3’)
运行结果:
c
中文操作一定要注意对中文 bitcount 进行统计时,是有区别的。现用的是 utf8。如果是 utf8 的话,中文的显示就是三个字节,三字节一个中文字符表示三字节。
如图所示:
如果用 gbk 的话,是两个字节。
如图所示:
注意:无论什么客户端,编码不一样,中文的字节就是不一样,bitcount 结果就是不一样。
#chinese
encoding
r, set(‘中’,’中文’)
print r,bitcount(‘中’)
注意慎用以下两个:
清楚当前库数据
- FLUSHDB
清除所有库中的数据
- FLUSHALL
1、位图bitmap
举个例子:
比如网站用户的上线次数统计(活跃用户),可用位图做用户上线。比如,设置u500,作为用户的一个ID,今年的第1天上线就是把第一个位置作为1,第30天上线是把第30个位置设为1,今年有几天上线就进行 bitcount,有几个1就表示有几天上线。通过位图进行操作计算就比直接代入算得快。而且还记录是哪一天上线的位置。
代码如下:
SETBIT u500 1 1(默认是0,现设为1)
S
ETBIT u500 30 1
B
ITCOUNT u500
(integer)2(表示这一个月用户有几天上线,进而通过这个值来判断用户是否为活跃用户)
K
EYS u*
通过以上例子,可以通过位图来操作用户上线次数的统计。每个用户都可做键,进行统计这个月或者一年有几天上线,进而可根据值来判断用户是否为活跃用户。
用户ID就是表示字符串类型。二进制的显示 utf8,没办法显示0101类型的。
1
27.0.0.1
:6
379
>
type u500
string
1
27.0.0.1
:6
379
>
get u500
“@\x00\x00\x02”
例子:
按天来统计网站活跃用户。比如:天作为 key,用户 ID 为 offset,求一段时间内活跃用户的数量。将20160602日第15个位置作为1,即可认为用户 ID 为15的上线。
如果还有用户,14也上线,就进行 SETBIT,把14的键的位置设为1,就可通过bitcount 统计这一天有几个用户上线。比如说123的用户,123的位置,6月1号是1,6月2号是0,到6月6号是1,一直到6月10号。如果用的是 OR,只要出现1,就认为活跃在这段时间。这样一步操作就能把一段时间内活跃用户都找出来。在BITCOUNT,有多少个。
代码如下:
S
ETBIT 20160602 15 1
SETBIT 20160601 123 1 (表示:2016年6月1号这天有几个用户上线,如果有用户上线,就设用户的位置设为1。)
SETBIT 20160606 123 1(以上的键都表示1个位图)
求6月1日到6月10日的活跃用户
BITOP
OR
20160601
-
10 20160601 20160602 20160603 20160610
BITCOUNT 20160601-10(用OR或,只要在这些天出现过即可认为上线过。用键来进行异或操作,从6月1号到6月10号。)
运行结果:
2.举例子的目的
为了让大家知道很多的需求是可以通过 RedB 里的位图的结构进行快速的计算,不需要将数据读出再进行统计。
用户 u1 的 key 将第一个位置设为1,如果第一天上线,就为1。如果用户第30天上线,就为1。关于用户 u1这一年上线情况都在键里,都可以体现出来。
代码如下:
r.setbit(‘u2’,110 ,1)
r
.setbit(‘u2’,300,1)
u2 也是一样的。
下面做 for 循环,在 for 循环里,把 u101,位图里的位置都设为了1。
代码如下:
for i in range(3,365,3);(表示从3到365,每隔set3)
r.setbit(‘u101’,i,1)(setbit位数,就设为1)
表示的是用户在好多天内上线的次数。类似 u105,代码如下:
for i in range(4,365,2); (表示从4到365,每隔2)
r.setbit(‘u105’,i,1) (setbit 位数,就设为1)
u
erList=r.keys(‘u’)
p
rint uerList
其实,从u101到105都是表示用户在这一年内有很多天上线。
Au 表示活跃用户,Nau 表示的是非活跃用户,用下面的代码可将这两类用户区分开。
Au=[]
Nau=[]
f
or u in uerList:
loginCount=r.bitcount(u) (用户上线的次数,bitcount 观察位图里有几个1。)
if loginCount>100: (如果上线次数大于100)
Au.append((u,loginCount))(就将用户加到 Au 的列表里)
else:
Nau.append((u,loginCount))(如果上线次数不足100,就加到 Nau 里)
首先,这里设置四个键,表示四个用户,接着setbit就将它当做位图来使用。
r.setbit(‘u1’,1, 1)就会有很多个位置,将第一个位置设为了1,代表的含义是,它第一天上线一次;第30天又上线一次,那说明它上线了两次。u2 在第110天上线一次,第300天又上线。
说明它一年内上线两次,它是非活跃用户。非活跃用户就包括 u1 和 u2。相对应于u101和u105用户这一年内有多次上线,通过两个 for 循环不断往里设置位数。
最后通过 keys 来判断这些 key,通过 uerList=r.keys(‘u*’)可取得这些键,然后便利这些键,通过 bitcoun t来统计这些键的位图的值,有几个1就统计出这一年上线的次数。将这个值 loginCount 与100进行判断,如果出现的次数大于100,就加到活跃用户里;小于100就加到非活跃用户里。
接着进行打印,便利了两个列表,打印了121,代码如下:
#
u1
r.setbit(‘u1’,1, 1)
r
.setbit(‘u1’,30,1)
#
u2
r.setbit(‘u2’,110 1)
r
.setbit(‘u2’,300,1)
#u101
f
or
i in range(3,365,3);
r.setbit(‘u101’,i,1)
#
u101
f
or
i in range(4,365,2);
r.setbit(‘u105’,i,1)
u
erList=r.keys(‘u*’)
p
rint uerList
Au=[]
Nau=[]
f
or u in uerList:
loginCount=r.bitcount(u) (用户上线的次数,bitcount 观察位图里有几个1。)
if loginCount>100: (如果上线次数大于100)
Au.append((u,loginCount))(就将用户加到Au的列表里)
else:
Nau.append((u,loginCount))(如果上线次数不足100,就加到 Nau 里)
for 1 in Au:
print1[0]+’is a Axtive User’,+str(1[1])
print”~~~~~~~~~~~~~~~~~~~~~~~~~”
for 1 in Nau:
print 1[0]+’is not a Active User’,+str(1[1])
运行结果:
[
‘u105’,’u2’,’u101’,’u1’]
u105 is a Active User.181(181,121分别表示这一年上线的次数)
u101 is a Active User.121
u2 is not a Active User.2(分别表示u1,u2上线的次数为2)
u1 is not a Active User.2
以上讲的是 Redis 数据模型里的字符串,最后的例子就是字符串的特例。
其里面有位图的操作,可以对位图里的某一位进行操作。可以通过 Bitop 或者是BItcount 统计位图里面有几个1,也可解决现实生活里面的需求,使需求的查询速度更快。