阅读 46

Redis数据结构大全

Redis数据结构大全

五大基本数据类型

Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。

Redis-key

在redis中无论什么数据类型,在数据库中都是以key-value形式保存,通过进行对Redis-key的操作,来完成对数据库中数据的操作。

下面学习的命令:

  • exists key:判断键是否存在

  • del key:删除键值对

  • move key db:将键值对移动到指定数据库

  • expire key second:设置键值对的过期时间

  • type key:查看value的数据类型

 127.0.0.1:6379> keys * # 查看当前数据库所有key  (empty list or set)  127.0.0.1:6379> set name qinjiang # set key  OK  127.0.0.1:6379> set age 20  OK  127.0.0.1:6379> keys *  1) "age"  2) "name"  127.0.0.1:6379> move age 1 # 将键值对移动到指定数据库  (integer) 1  127.0.0.1:6379> EXISTS age # 判断键是否存在  (integer) 0 # 不存在  127.0.0.1:6379> EXISTS name  (integer) 1 # 存在  127.0.0.1:6379> SELECT 1  OK  127.0.0.1:6379[1]> keys *  1) "age"  127.0.0.1:6379[1]> del age # 删除键值对  (integer) 1 # 删除个数      127.0.0.1:6379> set age 20  OK  127.0.0.1:6379> EXPIRE age 15 # 设置键值对的过期时间    (integer) 1 # 设置成功 开始计数  127.0.0.1:6379> ttl age # 查看key的过期剩余时间  (integer) 13  127.0.0.1:6379> ttl age  (integer) 11  127.0.0.1:6379> ttl age  (integer) 9  127.0.0.1:6379> ttl age  (integer) -2 # -2 表示key过期,-1表示key未设置过期时间    127.0.0.1:6379> get age # 过期的key 会被自动delete  (nil)  127.0.0.1:6379> keys *  1) "name"    127.0.0.1:6379> type name # 查看value的数据类型  string 复制代码

关于TTL命令

Redis的key,通过TTL命令返回key的过期时间,一般来说有3种:

  • 当前key没有设置过期时间,所以会返回-1

  • 当前key有设置过期时间,而且key已经过期,所以会返回-2.

  • 当前key有设置过期时间,且key还没有过期,故会返回key的正常剩余时间.

关于重命名RENAME和RENAMENX

  • RENAME key newkey修改 key 的名称

  • RENAMENX key newkey仅当 newkey 不存在时,将 key 改名为 newkey 。

更多命令学习:www.redis.net.cn/order/

String(字符串)

普通的set、get直接略过。

image-20221116194347306

image-20221116194408891

String类似的使用场景:value除了是字符串还可以是数字,用途举例:

  • 计数器

  • 统计多单位的数量:uid:123666:follow 0

  • 粉丝数

  • 对象存储缓存

List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)

一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

首先我们列表,可以经过规则定义将其变为队列、栈、双端队列等

image-20221116194508650

正如图Redis中List是可以进行双端操作的,所以命令也就分为了LXXX和RLLL两类,有时候L也表示List例如LLEN

image-20221116194556288

 ---------------------------LPUSH---RPUSH---LRANGE--------------------------------    127.0.0.1:6379> LPUSH mylist k1 # LPUSH mylist=>{1}  (integer) 1  127.0.0.1:6379> LPUSH mylist k2 # LPUSH mylist=>{2,1}  (integer) 2  127.0.0.1:6379> RPUSH mylist k3 # RPUSH mylist=>{2,1,3}  (integer) 3  127.0.0.1:6379> get mylist # 普通的get是无法获取list值的  (error) WRONGTYPE Operation against a key holding the wrong kind of value  127.0.0.1:6379> LRANGE mylist 0 4 # LRANGE 获取起止位置范围内的元素  1) "k2"  2) "k1"  3) "k3"  127.0.0.1:6379> LRANGE mylist 0 2  1) "k2"  2) "k1"  3) "k3"  127.0.0.1:6379> LRANGE mylist 0 1  1) "k2"  2) "k1"  127.0.0.1:6379> LRANGE mylist 0 -1 # 获取全部元素  1) "k2"  2) "k1"  3) "k3"    ---------------------------LPUSHX---RPUSHX-----------------------------------    127.0.0.1:6379> LPUSHX list v1 # list不存在 LPUSHX失败  (integer) 0  127.0.0.1:6379> LPUSHX list v1 v2    (integer) 0  127.0.0.1:6379> LPUSHX mylist k4 k5 # 向mylist中 左边 PUSH k4 k5  (integer) 5  127.0.0.1:6379> LRANGE mylist 0 -1  1) "k5"  2) "k4"  3) "k2"  4) "k1"  5) "k3"    ---------------------------LINSERT--LLEN--LINDEX--LSET----------------------------    127.0.0.1:6379> LINSERT mylist after k2 ins_key1 # 在k2元素后 插入ins_key1  (integer) 6  127.0.0.1:6379> LRANGE mylist 0 -1  1) "k5"  2) "k4"  3) "k2"  4) "ins_key1"  5) "k1"  6) "k3"  127.0.0.1:6379> LLEN mylist # 查看mylist的长度  (integer) 6  127.0.0.1:6379> LINDEX mylist 3 # 获取下标为3的元素  "ins_key1"  127.0.0.1:6379> LINDEX mylist 0  "k5"  127.0.0.1:6379> LSET mylist 3 k6 # 将下标3的元素 set值为k6  OK  127.0.0.1:6379> LRANGE mylist 0 -1  1) "k5"  2) "k4"  3) "k2"  4) "k6"  5) "k1"  6) "k3"    ---------------------------LPOP--RPOP--------------------------    127.0.0.1:6379> LPOP mylist # 左侧(头部)弹出  "k5"  127.0.0.1:6379> RPOP mylist # 右侧(尾部)弹出  "k3"    ---------------------------RPOPLPUSH--------------------------    127.0.0.1:6379> LRANGE mylist 0 -1  1) "k4"  2) "k2"  3) "k6"  4) "k1"  127.0.0.1:6379> RPOPLPUSH mylist newlist # 将mylist的最后一个值(k1)弹出,加入到newlist的头部  "k1"  127.0.0.1:6379> LRANGE newlist 0 -1  1) "k1"  127.0.0.1:6379> LRANGE mylist 0 -1  1) "k4"  2) "k2"  3) "k6"    ---------------------------LTRIM--------------------------    127.0.0.1:6379> LTRIM mylist 0 1 # 截取mylist中的 0~1部分  OK  127.0.0.1:6379> LRANGE mylist 0 -1  1) "k4"  2) "k2"    # 初始 mylist: k2,k2,k2,k2,k2,k2,k4,k2,k2,k2,k2  ---------------------------LREM--------------------------    127.0.0.1:6379> LREM mylist 3 k2 # 从头部开始搜索 至多删除3个 k2  (integer) 3  # 删除后:mylist: k2,k2,k2,k4,k2,k2,k2,k2    127.0.0.1:6379> LREM mylist -2 k2 #从尾部开始搜索 至多删除2个 k2  (integer) 2  # 删除后:mylist: k2,k2,k2,k4,k2,k2      ---------------------------BLPOP--BRPOP--------------------------    mylist: k2,k2,k2,k4,k2,k2  newlist: k1    127.0.0.1:6379> BLPOP newlist mylist 30 # 从newlist中弹出第一个值,mylist作为候选  1) "newlist" # 弹出  2) "k1"  127.0.0.1:6379> BLPOP newlist mylist 30  1) "mylist" # 由于newlist空了 从mylist中弹出  2) "k2"  127.0.0.1:6379> BLPOP newlist 30  (30.10s) # 超时了    127.0.0.1:6379> BLPOP newlist 30 # 我们连接另一个客户端向newlist中push了test, 阻塞被解决。  1) "newlist"  2) "test"  (12.54s)   复制代码

小结

  • list实际上是一个链表,before Node after , left, right 都可以插入值

  • 如果key不存在,则创建新的链表

  • 如果key存在,新增内容

  • 如果移除了所有值,空链表,也代表不存在

  • 在两边插入或者改动值,效率最高!修改中间元素,效率相对较低

应用:

消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)

Set(集合)

Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)

image-20221117165849403

 ---------------SADD--SCARD--SMEMBERS--SISMEMBER--------------------    127.0.0.1:6379> SADD myset m1 m2 m3 m4 # 向myset中增加成员 m1~m4  (integer) 4  127.0.0.1:6379> SCARD myset # 获取集合的成员数目  (integer) 4  127.0.0.1:6379> smembers myset # 获取集合中所有成员  1) "m4"  2) "m3"  3) "m2"  4) "m1"  127.0.0.1:6379> SISMEMBER myset m5 # 查询m5是否是myset的成员  (integer) 0 # 不是,返回0  127.0.0.1:6379> SISMEMBER myset m2  (integer) 1 # 是,返回1  127.0.0.1:6379> SISMEMBER myset m3  (integer) 1    ---------------------SRANDMEMBER--SPOP----------------------------------    127.0.0.1:6379> SRANDMEMBER myset 3 # 随机返回3个成员  1) "m2"  2) "m3"  3) "m4"  127.0.0.1:6379> SRANDMEMBER myset # 随机返回1个成员  "m3"  127.0.0.1:6379> SPOP myset 2 # 随机移除并返回2个成员  1) "m1"  2) "m4"  # 将set还原到{m1,m2,m3,m4}    ---------------------SMOVE--SREM----------------------------------------    127.0.0.1:6379> SMOVE myset newset m3 # 将myset中m3成员移动到newset集合  (integer) 1  127.0.0.1:6379> SMEMBERS myset  1) "m4"  2) "m2"  3) "m1"  127.0.0.1:6379> SMEMBERS newset  1) "m3"  127.0.0.1:6379> SREM newset m3 # 从newset中移除m3元素  (integer) 1  127.0.0.1:6379> SMEMBERS newset  (empty list or set)    # 下面开始是多集合操作,多集合操作中若只有一个参数默认和自身进行运算  # setx=>{m1,m2,m4,m6}, sety=>{m2,m5,m6}, setz=>{m1,m3,m6}    -----------------------------SDIFF------------------------------------    127.0.0.1:6379> SDIFF setx sety setz # 等价于setx-sety-setz  1) "m4"  127.0.0.1:6379> SDIFF setx sety # setx - sety  1) "m4"  2) "m1"  127.0.0.1:6379> SDIFF sety setx # sety - setx  1) "m5"      -------------------------SINTER---------------------------------------  # 共同关注(交集)    127.0.0.1:6379> SINTER setx sety setz # 求 setx、sety、setx的交集  1) "m6"  127.0.0.1:6379> SINTER setx sety # 求setx sety的交集  1) "m2"  2) "m6"    -------------------------SUNION---------------------------------------    127.0.0.1:6379> SUNION setx sety setz # setx sety setz的并集  1) "m4"  2) "m6"  3) "m3"  4) "m2"  5) "m1"  6) "m5"  127.0.0.1:6379> SUNION setx sety # setx sety 并集  1) "m4"  2) "m6"  3) "m2"  4) "m1"  5) "m5"   复制代码

 127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijin  (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 chongqi  (integer) 1  127.0.0.1:6379> GEOADD china:city 114.05 22.52 shenzhen  (integer) 1  127.0.0.1:6379> GEOADD china:city 120.16 30.24 hangzhou  (integer) 1  127.0.0.1:6379> GEOADD china:city 108.96 34.26 xian   复制代码

 127.0.0.1:6379> GEOPOS china:city beijin chongqi  1) 1) "116.39999896287918091"     2) "39.90000009167092543"  2) 1) "106.49999767541885376"     2) "29.52999957900659211"  127.0.0.1:6379>    复制代码

Hash(哈希)

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

Set就是一种简化的Hash,只变动key,而value使用默认值填充。可以将一个Hash表作为一个对象进行存储,表中存放对象的信息。

image-20221117165949348

 ------------------------HSET--HMSET--HSETNX----------------  127.0.0.1:6379> HSET studentx name sakura # 将studentx哈希表作为一个对象,设置name为sakura  (integer) 1  127.0.0.1:6379> HSET studentx name gyc # 重复设置field进行覆盖,并返回0  (integer) 0  127.0.0.1:6379> HSET studentx age 20 # 设置studentx的age为20  (integer) 1  127.0.0.1:6379> HMSET studentx sex 1 tel 15623667886 # 设置sex为1,tel为15623667886  OK  127.0.0.1:6379> HSETNX studentx name gyc # HSETNX 设置已存在的field  (integer) 0 # 失败  127.0.0.1:6379> HSETNX studentx email 12345@qq.com  (integer) 1 # 成功    ----------------------HEXISTS--------------------------------  127.0.0.1:6379> HEXISTS studentx name # name字段在studentx中是否存在  (integer) 1 # 存在  127.0.0.1:6379> HEXISTS studentx addr  (integer) 0 # 不存在    -------------------HGET--HMGET--HGETALL-----------  127.0.0.1:6379> HGET studentx name # 获取studentx中name字段的value  "gyc"  127.0.0.1:6379> HMGET studentx name age tel # 获取studentx中name、age、tel字段的value  1) "gyc"  2) "20"  3) "15623667886"  127.0.0.1:6379> HGETALL studentx # 获取studentx中所有的field及其value   1) "name"   2) "gyc"   3) "age"   4) "20"   5) "sex"   6) "1"   7) "tel"   8) "15623667886"   9) "email"  10) "12345@qq.com"      --------------------HKEYS--HLEN--HVALS--------------  127.0.0.1:6379> HKEYS studentx # 查看studentx中所有的field  1) "name"  2) "age"  3) "sex"  4) "tel"  5) "email"  127.0.0.1:6379> HLEN studentx # 查看studentx中的字段数量  (integer) 5  127.0.0.1:6379> HVALS studentx # 查看studentx中所有的value  1) "gyc"  2) "20"  3) "1"  4) "15623667886"  5) "12345@qq.com"    -------------------------HDEL--------------------------  127.0.0.1:6379> HDEL studentx sex tel # 删除studentx 中的sex、tel字段  (integer) 2  127.0.0.1:6379> HKEYS studentx  1) "name"  2) "age"  3) "email"    -------------HINCRBY--HINCRBYFLOAT------------------------  127.0.0.1:6379> HINCRBY studentx age 1 # studentx的age字段数值+1  (integer) 21  127.0.0.1:6379> HINCRBY studentx name 1 # 非整数字型字段不可用  (error) ERR hash value is not an integer  127.0.0.1:6379> HINCRBYFLOAT studentx weight 0.6 # weight字段增加0.6  "90.8"   复制代码

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

Hash更适合于对象的存储,Sring更加适合字符串存储!

Zset(有序集合)

不同的是每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大的排序。

score相同:按字典顺序排序

有序集合的成员是唯一的,但分数(score)却可以重复

image-20221117170123315

image-20221117170146797

 -------------------ZADD--ZCARD--ZCOUNT--------------  127.0.0.1:6379> ZADD myzset 1 m1 2 m2 3 m3 # 向有序集合myzset中添加成员m1 score=1 以及成员m2 score=2..  (integer) 2  127.0.0.1:6379> ZCARD myzset # 获取有序集合的成员数  (integer) 2  127.0.0.1:6379> ZCOUNT myzset 0 1 # 获取score在 [0,1]区间的成员数量  (integer) 1  127.0.0.1:6379> ZCOUNT myzset 0 2  (integer) 2    ----------------ZINCRBY--ZSCORE--------------------------  127.0.0.1:6379> ZINCRBY myzset 5 m2 # 将成员m2的score +5  "7"  127.0.0.1:6379> ZSCORE myzset m1 # 获取成员m1的score  "1"  127.0.0.1:6379> ZSCORE myzset m2  "7"    --------------ZRANK--ZRANGE-----------------------------------  127.0.0.1:6379> ZRANK myzset m1 # 获取成员m1的索引,索引按照score排序,score相同索引值按字典顺序顺序增加  (integer) 0  127.0.0.1:6379> ZRANK myzset m2  (integer) 2  127.0.0.1:6379> ZRANGE myzset 0 1 # 获取索引在 0~1的成员  1) "m1"  2) "m3"  127.0.0.1:6379> ZRANGE myzset 0 -1 # 获取全部成员  1) "m1"  2) "m3"  3) "m2"    #testset=>{abc,add,amaze,apple,back,java,redis} score均为0  ------------------ZRANGEBYLEX---------------------------------  127.0.0.1:6379> ZRANGEBYLEX testset - + # 返回所有成员  1) "abc"  2) "add"  3) "amaze"  4) "apple"  5) "back"  6) "java"  7) "redis"  127.0.0.1:6379> ZRANGEBYLEX testset - + LIMIT 0 3 # 分页 按索引显示查询结果的 0,1,2条记录  1) "abc"  2) "add"  3) "amaze"  127.0.0.1:6379> ZRANGEBYLEX testset - + LIMIT 3 3 # 显示 3,4,5条记录  1) "apple"  2) "back"  3) "java"  127.0.0.1:6379> ZRANGEBYLEX testset (- [apple # 显示 (-,apple] 区间内的成员  1) "abc"  2) "add"  3) "amaze"  4) "apple"  127.0.0.1:6379> ZRANGEBYLEX testset [apple [java # 显示 [apple,java]字典区间的成员  1) "apple"  2) "back"  3) "java"    -----------------------ZRANGEBYSCORE---------------------  127.0.0.1:6379> ZRANGEBYSCORE myzset 1 10 # 返回score在 [1,10]之间的的成员  1) "m1"  2) "m3"  3) "m2"  127.0.0.1:6379> ZRANGEBYSCORE myzset 1 5  1) "m1"  2) "m3"    --------------------ZLEXCOUNT-----------------------------  127.0.0.1:6379> ZLEXCOUNT testset - +  (integer) 7  127.0.0.1:6379> ZLEXCOUNT testset [apple [java  (integer) 3    ------------------ZREM--ZREMRANGEBYLEX--ZREMRANGBYRANK--ZREMRANGEBYSCORE--------------------------------  127.0.0.1:6379> ZREM testset abc # 移除成员abc  (integer) 1  127.0.0.1:6379> ZREMRANGEBYLEX testset [apple [java # 移除字典区间[apple,java]中的所有成员  (integer) 3  127.0.0.1:6379> ZREMRANGEBYRANK testset 0 1 # 移除排名0~1的所有成员  (integer) 2  127.0.0.1:6379> ZREMRANGEBYSCORE myzset 0 3 # 移除score在 [0,3]的成员  (integer) 2      # testset=> {abc,add,apple,amaze,back,java,redis} score均为0  # myzset=> {(m1,1),(m2,2),(m3,3),(m4,4),(m7,7),(m9,9)}  ----------------ZREVRANGE--ZREVRANGEBYSCORE--ZREVRANGEBYLEX-----------  127.0.0.1:6379> ZREVRANGE myzset 0 3 # 按score递减排序,然后按索引,返回结果的 0~3  1) "m9"  2) "m7"  3) "m4"  4) "m3"  127.0.0.1:6379> ZREVRANGE myzset 2 4 # 返回排序结果的 索引的2~4  1) "m4"  2) "m3"  3) "m2"  127.0.0.1:6379> ZREVRANGEBYSCORE myzset 6 2 # 按score递减顺序 返回集合中分数在[2,6]之间的成员  1) "m4"  2) "m3"  3) "m2"  127.0.0.1:6379> ZREVRANGEBYLEX testset [java (add # 按字典倒序 返回集合中(add,java]字典区间的成员  1) "java"  2) "back"  3) "apple"  4) "amaze"    -------------------------ZREVRANK------------------------------  127.0.0.1:6379> ZREVRANK myzset m7 # 按score递减顺序,返回成员m7索引  (integer) 1  127.0.0.1:6379> ZREVRANK myzset m2  (integer) 4      # mathscore=>{(xm,90),(xh,95),(xg,87)} 小明、小红、小刚的数学成绩  # enscore=>{(xm,70),(xh,93),(xg,90)} 小明、小红、小刚的英语成绩  -------------------ZINTERSTORE--ZUNIONSTORE-----------------------------------  127.0.0.1:6379> ZINTERSTORE sumscore 2 mathscore enscore # 将mathscore enscore进行合并 结果存放到sumscore  (integer) 3  127.0.0.1:6379> ZRANGE sumscore 0 -1 withscores # 合并后的score是之前集合中所有score的和  1) "xm"  2) "160"  3) "xg"  4) "177"  5) "xh"  6) "188"    127.0.0.1:6379> ZUNIONSTORE lowestscore 2 mathscore enscore AGGREGATE MIN # 取两个集合的成员score最小值作为结果的  (integer) 3  127.0.0.1:6379> ZRANGE lowestscore 0 -1 withscores  1) "xm"  2) "70"  3) "xg"  4) "87"  5) "xh"  6) "93"   复制代码

应用案例:

  • set排序 存储班级成绩表 工资表排序!

  • 普通消息,1.重要消息 2.带权重进行判断

  • 排行榜应用实现,取Top N测试

三种特殊数据类型

Geospatial(地理位置)

使用经纬度定位地理坐标并用一个有序集合zset保存,所以zset命令也可以使用

image-20221117170238577

有效经纬度

  • 有效的经度从-180度到180度。

  • 有效的纬度从-85.05112878度到85.05112878度。

指定单位的参数 unit 必须是以下单位的其中一个:

  • m 表示单位为米。

  • km 表示单位为千米。

  • mi 表示单位为英里。

  • ft 表示单位为英尺。

于GEORADIUS的参数

通过georadius就可以完成 附近的人功能

withcoord:带上坐标

withdist:带上距离,单位与半径单位相同

COUNT n : 只显示前n个(按距离递增排序)

 ----------------georadius---------------------  127.0.0.1:6379> GEORADIUS china:city 120 30 500 km withcoord withdist # 查询经纬度(120,30)坐标500km半径内的成员  1) 1) "hangzhou"     2) "29.4151"     3) 1) "120.20000249147415"        2) "30.199999888333501"  2) 1) "shanghai"     2) "205.3611"     3) 1) "121.40000134706497"        2) "31.400000253193539"         ------------geohash---------------------------  127.0.0.1:6379> geohash china:city yichang shanghai # 获取成员经纬坐标的geohash表示  1) "wmrjwbr5250"  2) "wtw6ds0y300"   复制代码

Hyperloglog(基数统计)

什么是基数?

数据集中不重复的元素的个数。

A{1,3,5,7,8,9}

B{1,3,5,7,8}

基数(不重复的元素) = 5 可以接受误差!

简介:

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。

因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

其底层使用string数据类型

应用场景:

网页的访问量(UV):一个用户多次访问,也只能算作一个人。

传统实现,存储用户的id,然后每次进行比较。当用户变多之后这种方式及其浪费空间,而我们的目的只是计数,Hyperloglog就能帮助我们利用最小的空间完成。

image-20221117170439480

 ----------PFADD--PFCOUNT---------------------  127.0.0.1:6379> PFADD myelemx a b c d e f g h i j k # 添加元素  (integer) 1  127.0.0.1:6379> type myelemx # hyperloglog底层使用String  string  127.0.0.1:6379> PFCOUNT myelemx # 估算myelemx的基数  (integer) 11  127.0.0.1:6379> PFADD myelemy i j k z m c b v p q s  (integer) 1  127.0.0.1:6379> PFCOUNT myelemy  (integer) 11    ----------------PFMERGE-----------------------  127.0.0.1:6379> PFMERGE myelemz myelemx myelemy # 合并myelemx和myelemy 成为myelemz  OK  127.0.0.1:6379> PFCOUNT myelemz # 估算基数  (integer) 17   复制代码

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

如果不允许容错,就使用set或者自己的数据类型即可 !

BitMaps(位图)

使用位存储,信息状态只有 0 和 1

Bitmap是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset),在bitmap上可执行AND,OR,XOR,NOT以及其它位操作。

应用场景

签到统计、状态统计

image-20221117170647201

 ------------setbit--getbit--------------  127.0.0.1:6379> setbit sign 0 1 # 设置sign的第0位为 1   (integer) 0  127.0.0.1:6379> setbit sign 2 1 # 设置sign的第2位为 1  不设置默认 是0  (integer) 0  127.0.0.1:6379> setbit sign 3 1  (integer) 0  127.0.0.1:6379> setbit sign 5 1  (integer) 0  127.0.0.1:6379> type sign  string    127.0.0.1:6379> getbit sign 2 # 获取第2位的数值  (integer) 1  127.0.0.1:6379> getbit sign 3  (integer) 1  127.0.0.1:6379> getbit sign 4 # 未设置默认是0  (integer) 0    -----------bitcount----------------------------  127.0.0.1:6379> BITCOUNT sign # 统计sign中为1的位数  (integer) 4


作者:蜡笔小新丶henry
链接:https://juejin.cn/post/7168867437897596965


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐