Redis特殊数据类型-Hyperloglog和Bitmap

77 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情

1 Hyperloglog(基数统计的算法,Redis2.8.9版本就已经更新出来了Hyperloglog 的数据结构,Hyperloglog有着0.81%的错误率,是可以忽略不计的)

学习之前先知道,什么是基数?

比如我有两个数据集 一个为A{1,3,5,7,8,7} 一个为B{1,3,5,7,8}

那么A和B的基数(不重复的元素)为5(1.3,5,7,8),可以接受误差

Hyperloglog的优点

1.占用的内存是固定的(比如说我想放2的64次方不同元素的基数,只需要费12KB的内存),如果要从内存角度来比较的话,Hyperloglog肯定是我们的首选

应用场景:

1 网页的UV(页面访问量,一个人访问一个网站多次,但是还是算作一个人)Hyperloglog有着0.81%的错误率,用作统计UV任务时,是可以忽略不计的(如果允许容错,那么一定可以使用Hyperloglog,如果不允许容错的话可以使用下面的传统set方式或者自己的数据类型即可)

传统的方式,使用set集合的方式保存用户的id等信息(因为set是不允许重复的,然后就可以统计出set中的元素数量作为标准判断),这个方式如果保存大量的用户id,就会比较麻烦(比较占用内存,我们的目的是为了计数,而不是保存用户信息)

Hyperloglog的命令

1 pfadd(name)(v1)(v2)(v3).....创建一组元素并且可以一次性添加多个值
2 pfcount(name)统计一组元素中的基数数量
3 pfmerge (new)(od1) (od2)统计两个老元素中的并集结果集并创建返回给新元素
127.0.0.1:6379[2]> pfadd mykey a b c d e f g h i j #创建第一组元素一次性添加多个值多个值

(integer) 1 #创建成功

127.0.0.1:6379[2]> pfadd mykey2 i j z x c v b n m #创建第二组元素一次性添加多个值多个值

(integer) 1 #创建成功

127.0.0.1:6379[2]> pfcount mykey #统计mykey中基数数量

(integer) 10 #有10个元素

127.0.0.1:6379[2]> pfcount mykey2 #统计mykey2中基数数量

(integer) 9 #有9个元素

127.0.0.1:6379[2]> pfmerge mykey3 mykey mykey2 #合并mykey mykey2把结果集(并集)赋给新元素mykey3

OK

127.0.0.1:6379[2]> pfcount mykey3  #统计mykey3中基数数量

(integer) 15 #有15个元素

127.0.0.1:6379[2]> pfadd k 1 #一次性添加一个值

(integer) 1

127.0.0.1:6379[2]> pfadd k 2 #一次性添加二个值

(integer) 1

127.0.0.1:6379[2]> pfcount k #统计k中基数数量

(integer) 2

2 Bitmap(位图,数据结构,都是操作二进制来进行记录,只有两个状态)

按位存储

Bitmap的使用场景:

1 统计用户信息,活跃,不活跃

2 打卡,两个状态的,都可以使用Bitmap

Bitmap的方法:

场景:使用bitmaps来实现周一到周五的打卡,下表从0开始打卡:1 不打卡:0,判断打卡天数,只需要统计状态为1的即可,例如:周一(0)打卡(1),周二(1)不打卡(0)
1 setbit(name)(sign1) (sign2) 设置元素,一般有两个状态
2 getbit(name)(sign) 根据状态获取某一个值
3 bitcount(name)统计全部的元素个数
1127.0.0.1:6379[2]> setbit sign  0 1 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0)

(integer) 0

127.0.0.1:6379[2]> setbit sign  1 0 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0)

(integer) 0

127.0.0.1:6379[2]> setbit sign  2 0 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0)

(integer) 0

127.0.0.1:6379[2]> setbit sign  3 1 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0)

(integer) 0

127.0.0.1:6379[2]> setbit sign  4 1 #添加元素例如:周一(0)打卡(1),周二(1)不打卡(0)

(integer) 0

127.0.0.1:6379[2]> getbit sign 0 #查看周一是否打卡

(integer) 1 #打卡

127.0.0.1:6379[2]> getbit sign 1 #查看周二是否打卡

(integer) 0 #没打卡

127.0.0.1:6379[2]>  bitcount sign #查看周一到周五打卡的全部天数

(integer) 3
  1. Redis基础的一些知识和命令

命令

  1. ping(有没有连接到.返回pong表示连接成功)

  2. set get(set name wyh get name)

  3. 清除全部的数据库内容 flushall

  4. 清除当前数据库flushdb

  5. Keys(*)查看全部的键

  6. exists(key) 查看键是否存在,存在的话返回1,不存在返回0

  7. select进行切换数据库

  8. clear清屏

  9. move key numb (键,移动到那个数据库) 移动属性到指定的数据库

  10. expire (name 10 )设置某个键的过期时间(单位是秒s)

  11. ttl (key) 查看当前某个键的剩余时间,过期的话返回负数

  12. type 查看数据类型 type(key)

127.0.0.1:6379[5]> ping #测试连接

PONG                     #连接成功

127.0.0.1:6379[1]> select 0 #切换数据库0

OK

127.0.0.1:6379> select 1 #切换数据库0

OK

127.0.0.1:6379[1]> set name wyh #设置key键

OK

127.0.0.1:6379[1]> set age 22  #设置key键

OK

127.0.0.1:6379[1]> keys * #查看全部的键

1) "name"

2) "age"

127.0.0.1:6379[1]> get name

"wyh"

127.0.0.1:6379[1]> exists age #判断是否存在

(integer) 1

127.0.0.1:6379[1]> flushdb # 刷新当期数据库

OK

127.0.0.1:6379[1]> flushall #刷新全部数据库

OK

127.0.0.1:6379[1]> clear #清空

127.0.0.1:6379[2]> set animal dog #设置属性

OK

127.0.0.1:6379[2]> move animal 5 #把animal键移动到数据库5

(integer) 1

127.0.0.1:6379[2]> keys *  #查看全部的键

1) "age"

127.0.0.1:6379[2]> select 5 #切换到数据库5

OK

127.0.0.1:6379[5]> keys * #查看全部的键

1) "animal"

127.0.0.1:6379[2]> expire name 10  #设置过期时间10秒

(integer) 1 #成功的话返回1 不成功返回0

127.0.0.1:6379[2]> ttl name #查看剩余过期时间

(integer) 6

127.0.0.1:6379[2]> ttl name #查看当前key的剩余过期时间

(integer) 1

127.0.0.1:6379[2]> ttl name #查看当前key的剩余过期时间

(integer) -2 #已经过期2秒

127.0.0.1:6379[2]> get name #查看name,已经过期

(nil) #没有了,说明已经过期

127.0.0.1:6379[2]> type age #查看key的类型

string

127.0.0.1:6379[2]> type name #查看key的类型 

string

知识

  1. redis默认有16个数据库

  2. 默认的使用的是第0个

  3. 可以使用select进行切换数据库!

  4. 清除全部的数据库内容 flushall

  5. 清除当前数据库flushdb