重学之路--Redis(1)

基于狂神视频的笔记

Nosql概述

为什么Nosql

  1. 原来的架构–单机Mysql
    在这里插入图片描述
  2. Memcached(缓存)+mysql+垂直拆分(读写分离)
    减轻数据的压力 使用缓存来保证效率
    在这里插入图片描述
  3. 分库分表 +水平拆分+Mysql集群
    本质:数据库(读,写)
    早些年MyISAM:表锁,十分影响效率!高并发下就会出现严重的锁问题
    转战Innodb:行锁
    慢慢就开始使用分库分表来解决写的压力!
    在这里插入图片描述
  4. 如今的年代
    Mysql等关系型数据库就不够用了!数据量很多,变化很快~!
    目前基本互联网架构
    在这里插入图片描述

什么是NoSQL

nosql =not only sql 泛指非关系型数据库
很多的数据类型用户的个人信息,社交网络,地理位置等。这些数据类型的存储不需要一个固定的格式!
NoSQL特点

  1. 方便扩展(数据之间没有关系,很好扩展!)
  2. 大数据量高性能(Redis 一秒写8w次,读取11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能会比较高)
  3. 数据类型是多样型的!(不需要事先设计数据库!随取随用!)
  4. 传统的RDBMS 和 NoSQL
传统的RDMBMS
- 结构化组织
- sql
- 数据和关系都存在单独的表中
- 操作,数据定义语言
- 严格的一致性
- 基础的事务
- 。。。。。
NoSQL
- 不仅仅是数据
- 没有固定的查询语言
- 键值对存储,列存储 文档存储 图形数据库(社交关系)
- 最终一致性
- CAP定理和BASE(异地多活)
- 高性能,高可用,高可扩
- 。。。。。

了解:3V+3高
大数据时代的3V:主要是描述问题
海量Velume
多样Variety
实时Velocity
大数据时代的3高:主要对程序的要求
高并发
高可扩(随时水平拆分,机器不够直接+)
高性能

阿里巴巴分析

# 1,商品的基本信息
		关系型数据库就可以解决
# 2,商品的描述,评论(文字比较多)
		文档型数据库,MongoDB
# 3,图片
		分布式文件系统 FastDFS
		- 淘宝自己的 TFS
		- Google的 GFS
		- Hadoop		HDFS
		- 阿里云		oss
# 4,商品的关键字(搜索)
	- 搜索引擎 solr elasticsearch
	- ISearch
# 5,商品热门的波段信息
	- 内存数据库
	- Redis Tair Memcache
# 6,商品的交易,外部的指出接口
	- 三方应用

大型互联网应用问题:

  • 数据类型太多了!
  • 数据源繁多,经常重构!
  • 数据要改造
    解决办法:统一数据服务从 -----UDSL:
    在这里插入图片描述
    在这里插入图片描述

NoSQL的四大分类

KV键值对:

  • 新浪:Redis
  • 美团:Redis+Tair
  • 阿里,百度:Redis—+memechache

文档型数据库(bson格式和json一样):

  • MangoDB (必须掌握)
    MangoDB是以后个基于分布式文件存储的数据库,C++编写,主要用来处理大量的文档!
    MangoDB椒词汇表介于关系型数据库和非关系型数据库中中间的产品! MongoDB是非关系型数据库中功能最丰富,最像关系型数据库 的!
  • ConthDB

列存储数据库

  • HBase
  • 分布式文件系统

图关系型数据库

  • 他不是存图形,放的是关系,比如:朋友前社交网络,广告推荐等
  • Neo4j,infoGrid

Redis入门

概述

redis是什么

Redis(Remote Dictionary Server ),即远程字典服务!

能干嘛?

1,内存存储,持久化(rdb,aof)
2,效率高 可以用于告诉缓存
3,发布订阅系统
4,地图信息分析
5,计时器,计数器
。。。。。

特性

1,多样的数据类型
2,持久化
3,集群
4,事务

中文官网:http://www.redis.cn/

Linux安装

# 1 下载安装包

# 2 解压后放入  /opt目录
[root@iZ2vc20ehn0q0ihrgccmd2Z xuanmeng]# tar -zxvf redis-6.0.6.tar.gz
[root@iZ2vc20ehn0q0ihrgccmd2Z xuanmeng]# mv redis-6.0.6 /opt/
[root@iZ2vc20ehn0q0ihrgccmd2Z opt]# ls
containerd  redis-6.0.6

# 3 安装基本的环境
yum install gcc-c++
make
make install
# 4 redis的 默认安装路径  /usr/local/bin/

# 5 将redis的配置文件 拷贝到当前目录下 /usr/local/bin/xxx

# 6 redis默认不是后台启动,修改配置文件!redis.conf daemonize 改为yes

# 7 启动redis服务!
[root@iZ2vc20ehn0q0ihrgccmd2Z bin]# redis-server xmconfig/redis.conf 

# 8 测试链接
[root@iZ2vc20ehn0q0ihrgccmd2Z bin]# redis-cli -p 6379
127.0.0.1:6379> 

# 9 查看redis进程是否开启
[root@iZ2vc20ehn0q0ihrgccmd2Z ~]# ps -ef|grep redis

# 10如何关闭redis  					shutdown

# 11 再次查看redis的进程

测试性能

redis-benchmark 是一个压力测试工具!
命令参数:
在这里插入图片描述
简单测试下:

# 测试:100个并发连接 100000个请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000

如何查看这些分析

基础知识

redis默认有16个数据库 默认使用第0个

使用select 切换数据库

[root@iZ2vc20ehn0q0ihrgccmd2Z bin]# redis-cli -p 6379
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> DBSIZE # 查看当前库的大小

# 查看所有的key
keys *

清除当前的数据库 flushdb
清除全部的数据库 flushall

flushdb

Redis是单线程的!
redis是基础内存操作,CPU不是Redis性能瓶颈, Redis的瓶颈是根据机器的内存和网络带宽!

Redis 为什么单线程还这么快?

  • 误区1: 高性能的服务器一定是多线程的?
  • 误区2:多线程(CPU上下文会切换!耗时)一定比单线程效率高!
    核心:redis将所有的数据放入内存中,所以使用单线程操作是最高的!对于内存系统来说 没有上下文切换效率就是最高的!多次读写都是在一个cpu上的 在内存情况下 这个就是最佳的方案!

五大数据类型

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

Redis-key

127.0.0.1:6379> select 2   					# 选择数据库
OK
127.0.0.1:6379[2]> DBSIZE 				# 当前DB大小 
(integer) 0
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> set name xm
OK
127.0.0.1:6379> get name
"xm"
127.0.0.1:6379> EXISTS name		# 判断 key是否存在
(integer) 1
127.0.0.1:6379> keys *					# 查看所有keys
1) "myzset"
2) "key:__rand_int__"
3) "counter:__rand_int__"
4) "name"
5) "myhash"
127.0.0.1:6379> EXPIRE name 10			#设置key的过期时间 单位 秒
(integer) 1
127.0.0.1:6379> ttl name						# 查看当前key的剩余时间
(integer) 2
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> set name xx
OK
127.0.0.1:6379> MOVE name 1				# 移除key到其他库
(integer) 1
127.0.0.1:6379> get name
127.0.0.1:6379[1]> type name			# 查看key的类型
string

官网命令地址:http://www.redis.cn/commands.html

String(字符串)

127.0.0.1:6379> set name xm					#设值
OK
127.0.0.1:6379> APPEND name 123			# 给key 追加字符串 (如果key不存在 相当于set key)
(integer) 5
127.0.0.1:6379> get name
"xm123"
127.0.0.1:6379> STRLEN name 				# 字符串长度
(integer) 5
#####################################
# i++
# 步长 i+=
127.0.0.1:6379> INCR views
(integer) 1
127.0.0.1:6379> INCR views
(integer) 2

127.0.0.1:6379> decr views
(integer) 1
127.0.0.1:6379> decr views
(integer) 0

127.0.0.1:6379> INCRBY views 10	# 指定增量
(integer) 8
127.0.0.1:6379> INCRBY views 10
(integer) 18
127.0.0.1:6379> DECRBY views 5		# 指定减量
(integer) 13
#####################################
# 字符串范围 range
127.0.0.1:6379> set name "hello,world!"
OK
127.0.0.1:6379> get name
"hello,world!"
127.0.0.1:6379> GETRANGE name 0 3
"hell"
127.0.0.1:6379> GETRANGE name 0 -1
"hello,world!"

# 替换
127.0.0.1:6379> set key1 hdhsahd
OK
127.0.0.1:6379> SETRANGE key1 4 jjs
(integer) 7
127.0.0.1:6379> get key1
"hdhsjjs"

#####################################
# setex (set with expire)  #设置过期时间
# setnx (set if not exist)   #不存在再设置(在分布式锁中会常常使用!)

127.0.0.1:6379> SETEX key3 30 "kbskbs"   设置key3 30秒过期

127.0.0.1:6379> SETNX mykey "springCloud"
(integer) 1
127.0.0.1:6379> SETNX mykey "springBoot"
(integer) 0
127.0.0.1:6379> get mykey
"springCloud"
#####################################
mset
mget

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> MSETNX k1 v2 k4 v4  # msetnx 是一个原子性的操作 要么一起成功 要么一起失败!
(integer) 0

# 对象
set user:1{name:xm,age:3}  # 设置一个user:1 对象 值为json字符来保存一个对象
# 这里的key是一个巧妙的设计: user:{id}:{filed}

127.0.0.1:6379> mset user:1:name xm user:1:age 32
OK

127.0.0.1:6379> mget user:1:name user:1:age
1) "xm"
2) "32"

#####################################
getset 				# 先get再set
127.0.0.1:6379> getset db redis			# 如果不存在值 则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb		# 如果存在值 获取原来的值 并设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"
#####################################

String 类似的使用场景: value除了是我们的字符串还可以是数字!

  • 计数器
  • 统计多单位的数量
  • 粉丝数
  • 对象缓存存储!

List

基本的数据类型,在redis中我们可以吧list 玩成 队列,栈,阻塞队列!
所有的List命令都是 l 开头

127.0.0.1:6379> LPUSH list 1		# lpush 插入到列表头部(左)
(integer) 1
127.0.0.1:6379> LPUSH list 2
(integer) 2
127.0.0.1:6379> LPUSH list 3
(integer) 3
127.0.0.1:6379> LRANGE list 0 1
1) "3"
2) "2"
127.0.0.1:6379> RPUSH list 4	# rpush 插入到列表尾部(右)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1  	# 利用区间获取具体值
1) "3"
2) "2"
3) "1"
4) "4"

###################################
127.0.0.1:6379> LPOP list 			# 移除list 第一个元素
"3"
127.0.0.1:6379> RPOP list			# 移除list 最后一个元素
"4"
###################################
127.0.0.1:6379> LINDEX list 1	# 通过下表获得list的某一个值

###################################
127.0.0.1:6379> LPUSH list 11
(integer) 1
127.0.0.1:6379> LPUSH list 22
(integer) 2
127.0.0.1:6379> LPUSH list 33
(integer) 3
127.0.0.1:6379> LLEN list				# list长度
(integer) 3
###################################
移除指定的值!  
127.0.0.1:6379> LREM list 1 11  # 移除1个 11内容
(integer) 1
###################################
trim 修剪: list截断!
127.0.0.1:6379> rpush list "hello1"
(integer) 1
127.0.0.1:6379> rpush list "hello2"
(integer) 2
127.0.0.1:6379> rpush list "hello3"
(integer) 3
127.0.0.1:6379> rpush list "hello4"
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "hello1"
2) "hello2"
3) "hello3"
4) "hello4"
127.0.0.1:6379> LTRIM list 1 2 				# 通过下表截取指定长度 list被改变 截断后只剩下截断的元素!

OK
127.0.0.1:6379> LRANGE list 0 -1
1) "hello2"
2) "hello3"
###################################
rpoplpush # 移除列表的最后一个元素
127.0.0.1:6379> LRANGE list 0 -1
1) "hello1"
2) "hello2"
3) "hello3"
4) "hello4"
127.0.0.1:6379> RPOPLPUSH list list2
"hello4"
127.0.0.1:6379> RPOPLPUSH list list2
"hello3"
127.0.0.1:6379> LRANGE list2 0 -1
1) "hello3"
2) "hello4"
###################################
lset 将列表中指定下标的值替换为另外一个值,更新操作
127.0.0.1:6379> LSET list 0 111			# 如果不存在列表 更新报错
(error) ERR no such key
127.0.0.1:6379> LPUSH list v1
(integer) 1
127.0.0.1:6379> lset list 0 v11			# 如果不存在列表 更新值
OK
127.0.0.1:6379> LRANGE list 0 -1
###################################
linsert # 将某个值插入到某个值的前后
127.0.0.1:6379> RPUSH list hello
(integer) 1
127.0.0.1:6379> RPUSH list world
(integer) 2
127.0.0.1:6379> LINSERT list before hello xm
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "xm"
2) "hello"
3) "world"

小结
消息队列:LPUSH RPOP 反过来一样(RPUSH LPOP)
栈:LPUSH LPOP

Set(集合)

set中的值是不能重复的! (无序不重复集合)

##############################################
127.0.0.1:6379> sadd myset hello    # set集合中添加元素
(integer) 1
127.0.0.1:6379> sadd myset world
(integer) 1
127.0.0.1:6379> sadd myset xm
(integer) 1
127.0.0.1:6379> SMEMBERS myset			# 查看指定set的所有值
1) "world"
2) "xm"
3) "hello"
127.0.0.1:6379> SISMEMBER myset hello		# 是否存在某个值
(integer) 1
127.0.0.1:6379> SISMEMBER myset 123
(integer) 0
##############################################
127.0.0.1:6379> SCARD myset		# 获取set集合中的元素个数
(integer) 3

##############################################
127.0.0.1:6379> SREM myset hello		# 移除set中的某个元素
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "world"
2) "xm"
##############################################
127.0.0.1:6379> SRANDMEMBER myset		# 随机抽选出一个元素
"world"
127.0.0.1:6379> SRANDMEMBER myset 2  # 随机抽选出n个元素
"xm"
"world"
##############################################
删除指定的key,随机删除key!
127.0.0.1:6379> SPOP myset  					# 随机删除一个值
"1232"

##############################################
将一个指定的值 移动到另外一个set集合
127.0.0.1:6379> sadd myset2 xxx
(integer) 1
127.0.0.1:6379> SMOVE myset myset2 hello
(integer) 1
127.0.0.1:6379> SMEMBERS myset2
1) "xxx"
2) "hello"
##############################################
- 并集  SUNION
- 交集	SINTER
- 差集	SDIFF
127.0.0.1:6379> sadd set1 a
(integer) 1
127.0.0.1:6379> sadd set1 b
(integer) 1
127.0.0.1:6379> sadd set1 c
(integer) 1
127.0.0.1:6379> sadd set2 c
(integer) 1
127.0.0.1:6379> sadd set2 d
(integer) 1
127.0.0.1:6379> sadd set2 e
(integer) 1
127.0.0.1:6379> SDIFF set1 set2		# 差集
1) "a"
2) "b"
127.0.0.1:6379> SINTER set1 set2 	# 交集
1) "c"
127.0.0.1:6379> SUNION set1 set2	# 并集
1) "a"
2) "b"
3) "c"
4) "e"
5) "d"

微博 A用户将所有关注的人放在一个set集合中!将他的粉丝也放在一个集合中! 共同关注等(六度分割理论)

Hash(哈希)

Map集合,key-map集合!本质和String类型没有太大区别!

127.0.0.1:6379> HSET myhash f1 xuanmeng			# set一个具体 k-v
(integer) 1
127.0.0.1:6379> hget myhash f1
"xuanmeng"
127.0.0.1:6379> HMSET myhash f1 xxx f2 ddd			# set多个 k-v
OK
127.0.0.1:6379> HMGET myhash f1 f2						# 获取多个字段值
1) "xxx"
2) "ddd"
127.0.0.1:6379> HGETALL myhash							# 获取全部数据
1) "f1"
2) "xxx"
3) "f2"
4) "ddd"
############################################
127.0.0.1:6379> HDEL myhash f1			# 删除hash指定key value也会删除
(integer) 1
127.0.0.1:6379> HGETALL myhash
1) "f2"
2) "ddd"
############################################
127.0.0.1:6379> HLEN myhash		# 获取字段数量
(integer) 4

############################################
127.0.0.1:6379> HEXISTS myhash f1		#判断hash指定字段是否存在!
(integer) 1
127.0.0.1:6379> HEXISTS myhash f5
(integer) 0

############################################

127.0.0.1:6379> HKEYS myhash   # 只获得所有filed
1) "f2"
2) "f1"
3) "f3"
4) "f4"
127.0.0.1:6379> HVALS myhash	# 只获得所有value值
1) "ddd"
2) "qqq"
3) "www"
4) "eee"

############################################
HINCRBY myhash f1 1			#指定增量! 如果不存在报错
DECRBY									# 指定减量!
127.0.0.1:6379> HSETNX myhash f5 ddd			#如果不存在则可以设置
(integer) 1
127.0.0.1:6379> HSETNX myhash f5 ddd			#如果存在则不能设置
(integer) 0

############################################

hash变更数据(user name age )尤其是用户信息之类 经常变动的信息!

Zset(有序集合)

在set的基础上 增加了一个值

127.0.0.1:6379> ZADD myset 1 noe
(integer) 1
127.0.0.1:6379> ZADD myset 2 two 3 three
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1
1) "noe"
2) "two"
3) "three"
############################################
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf		# 从小到大排序
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores	
1) "zhangsan"
2) "1000"
3) "lisi"
4) "5000"
5) "wangwu"
6) "5500"
127.0.0.1:6379> ZREVRANGE salary 0 -1 withscores			#从大到小排序
1) "wangwu"
2) "5500"
3) "lisi"
4) "5000"

127.0.0.1:6379> ZRANGEBYSCORE salary  1000 5000			# 1000-5000之间的排序
1) "zhangsan"
2) "lisi"
############################################
# 移除rem中的元素
127.0.0.1:6379> ZRANGE salary 0 -1
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> ZREM salary zhangsan			#移除某个元素
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "lisi"
2) "wangwu"
127.0.0.1:6379> ZCARD salary
(integer) 2

############################################
127.0.0.1:6379> zadd myset 1 hello
(integer) 1
127.0.0.1:6379> zadd myset 2 world 3 xm
(integer) 2
127.0.0.1:6379> ZCOUNT myset 1 3		#指定区间的成员数量!
(integer) 3

############################################

案例思路:set 排序 存储班级成绩 工资等
普通消息 1 重要 2 带权重判断!
排行榜应用实现!!

三种特殊数据类型

geospatial 地理位置

朋友定位,附近的人,打车距离计算!
geoadd

# geoadd 添加地理位置
# 规则:两极无法直接添加
# 参数 key 纬度 经度 名称
127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> GEOADD china:city 106.50 29.53 chongqing 114.05 22.52 shenzheng
(integer) 2
127.0.0.1:6379> GEOADD china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2

geopos 获得当前定位:一定是一个坐标值

127.0.0.1:6379> GEOPOS china:city beijing				# 获取指定城市的经度和纬度!
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city shanghai chongqing
1) 1) "121.47000163793563843"
   2) "31.22999903975783553"
2) 1) "106.49999767541885376"
   2) "29.52999957900659211"

geodist
两人之间的距离!
单位:

  • m 米
  • km 千米
  • mi 英里
  • ft 英尺
127.0.0.1:6379> GEODIST china:city beijing shanghai			#查看北京到上海的直线距离
"1067378.7564"
127.0.0.1:6379> GEODIST china:city beijing shanghai km
"1067.3788"

georadius 以指定的经纬度为中心 找出某一半径内的地方
我附近的人?

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km		# 以 110 30为中心 寻找方圆1000km内的城市(所有数据要在china:city中)
1) "chongqing"
2) "xian"
3) "shenzheng"
4) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist	# 显示到中心点的直线距离
1) 1) "chongqing"
   2) "341.9374"
2) 1) "xian"
   2) "483.8340"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord	# 显示他人的定位信息
1) 1) "chongqing"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.96000176668167114"
      2) "34.25999964418929977"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord withdist count 2
1) 1) "chongqing"
   2) "341.9374"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) "483.8340"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"

georadiusbymember

# 找出位于指定元素周围的其他元素!
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
2) "xian"

geohash : 返回一个或多个位置元素的geohash表示

GEO底层的实现原理其实就是Zset!

127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chongqing"
2) "xian"
3) "shenzheng"
4) "hangzhou"
5) "shanghai"
6) "beijing"
127.0.0.1:6379> ZREM china:city shenzheng
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chongqing"
2) "xian"
3) "hangzhou"
4) "shanghai"
5) "beijing"

Hyperloglog

什么是基数?
不重复的元素
A{1,3,5,7,8,7}
B{1,3,5,7,8}
基数=5 可以接受误差!
简介

优点:占用内存是固定
redis hyperloglog 基数统计的算法!
网页的UV(一个人访问一个网页多次,但是还是算一个人!)
传统方式 set保存用户的id 然后就可以统计set中的元素数量作为判断标准!
目的:用来计数

测试使用:
127.0.0.1:6379> PFADD mykey a b c d e f g h i j			# 创建第一组元素
(integer) 1
127.0.0.1:6379> PFCOUNT mykey								# 统计 基数数量
(integer) 10	
127.0.0.1:6379> PFADD mykey2 i j k l m						# 创建第二组元素
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 5
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2		# 合并两组 mykey mykey2 到 mykey3 并集
OK
127.0.0.1:6379> PFCOUNT mykey3
(integer) 13

如果允许容错 那么可以使用Hyperloglog!

Bitmaps

位存储

如 统计疫情感染人数: 0 1 0 1 0 0 0
统计用户信息,活跃,不活跃! 登录 未登录!打卡,不打卡!
2个状态的 都可以使Bitmaps
BitMaps 位图,数据结构! 都是操作二进制位来进行记录 只有0和1 两个状态!

使用bitmaps记录 周一到周日的打卡!

127.0.0.1:6379> SETBIT sign 0 0
(integer) 0
127.0.0.1:6379> SETBIT sign 1 1
(integer) 0
127.0.0.1:6379> SETBIT sign 2 0
(integer) 0
127.0.0.1:6379> SETBIT sign 3 1
(integer) 0
127.0.0.1:6379> SETBIT sign 4 1
(integer) 0
127.0.0.1:6379> SETBIT sign 5 1
(integer) 0
127.0.0.1:6379> SETBIT sign 6 0
(integer) 0
127.0.0.1:6379> GETBIT sign 3			# 查看
(integer) 1
127.0.0.1:6379> BITCOUNT sign		# 统计打卡天数!
(integer) 4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值