当前位置: 首页 > news >正文

【Redis】特殊的数据类型

每一个版本都会有不同的功能,根据所需要的点去官方文档查询学习

官方学习文档Commands

geospatial

命令学习

地图空间索引,见名知意,适用于进行经纬度记录,统计地理空间位置的功能;

我当前使用的redis版本为Redis 5.0.10;其中的部分功能如下显示:

  1. geoadd添加坐标
  2. geopos查询地理坐标
  3. geodist查询两个坐标之间的距离
  4. geohash将地理坐标返回为hash值进行返回,比较大时候可以通过hash值的相近度区分附近的人,值相差越大,位置相差偏差越大;

代码如下:

127.0.0.1:6379>  geoadd myaddress 115 39 address1 110 20 address2
(integer) 2
127.0.0.1:6379> geopos myaddress address1 address2
1) 1) "114.99999850988388062"2) "38.99999918434559731"
2) 1) "110.00000149011611938"2) "20.00000058910486445"
127.0.0.1:6379> geodist myaddress address1 address2
"2167037.9521"
127.0.0.1:6379> geodist myaddress address1 address2 km
"2167.0380"
127.0.0.1:6379> geohash myaddress address1 address2
1) "wwcvbgsrqn0"
2) "w7w1z0gs3y0"
127.0.0.1:6379> geoadd myaddress 115 33 address3 114 39 address4
(integer) 2
127.0.0.1:6379> geohash myaddress address1 address2 address3 address4
1) "wwcvbgsrqn0"
2) "w7w1z0gs3y0"
3) "wtcg8zkqyj0"
4) "wwcjf5sr2w0"

总结

  • GEO 使用了 Sorted Set 集合类型,并通过 GeoHash 编码方法实现了经纬度到 Sorted Set 中元素权重分数的转换,涵盖两个关键能力就是就是对二维地图做区间划分,以及对区间进行编码。
  • 具体可应用的场景如下:
    • 计算用户的精准的地理坐标位置
    • 统计用户定点坐标一定范围内的其他地理位置,并计算出距离
    • 对一定范围内的地理位置进行排序,并由近到远筛选
  • 真实的地图数据存储,场景比这复杂的多,数据量会达到惊人的巨量,所以还是会使用分治原理进行拆分,细化到一个市甚至一个区,来提高存储和检索的效率。

hyperloglog 海量数据统计

HyperLogLog 是在redis2.8.9介入的功能,用于进行基数记录,

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

基数

整个数组集合中的所有的基础数据,称之为基数,即不重复的元素;

{1,2,2,3,4,4,5} >> {1,2,3,4,5}

命令学习

应用场景:页面显示当日访问量,如果是是同一个人记录为1次

  1. pfadd 添加到key中内容;
  2. pfcount 统计key中的基数数量,误差值±5,允许容错的时候是可以的;
  3. pfmerge 将一个key的内容merge到 另一个key中;
127.0.0.1:6379> pfadd myopf aa1001 aa1003 aa002 0022a aa2002 aa1001 aa1001 aa1003
(integer) 1
127.0.0.1:6379> pfcount myopf
(integer) 5
127.0.0.1:6379> pfadd mypf2 aa1001 aa1002 bb1001 bb1002
(integer) 1
127.0.0.1:6379> pfcount mypf2
(integer) 4
127.0.0.1:6379> pfmerge myopf mypf2
OK
127.0.0.1:6379> pfcount mypf2
(integer) 4
127.0.0.1:6379> pfcount myopf
(integer) 8
127.0.0.1:6379>

bitmaps

位图 位存储

参照学习博客:https://www.cnblogs.com/wzh2010/p/15886801.html

应用场景:存储打卡数据,统计打卡数据

简述

位图(BitMap)的底层数据结构是使用String类型的SDS数据结构来存储。

一个字节8bit,为了将字节中的位都利用到位,使用数组结构来保存;

BitMap 是通过一个 bit 位来表示某个元素对应的值或者状态, 它的结构如下,key 对应元素本身;offset即是偏移量,固定整型,一般存数组下表或者唯一值;value存储的是二值(要么0要么1),一般用来表示状态,如性别、是否登录、是否打卡等。

SETBIT key offset value

key是元素名称,

offset 必须是数值类型,

value 只能是 0 或者 1,

如果我们存储一个用户的在线状态,用户,代码如下:

//设置在线状态 
// $redis->setBit('online', $uid, 1);$redis->setBit('online', 5, 1);
$redis->setBit('online', 9, 1);

命令学习

  1. setbit设置bit的value内容
  2. getbit获取bit的value内容
127.0.0.1:6379> setbit mysbit 0 1
(integer) 1
127.0.0.1:6379> getbit mysbit 0
(integer) 1
127.0.0.1:6379> setbit mysbit 0 0
(integer) 1
127.0.0.1:6379> getbit mysbit 0
(integer) 0
127.0.0.1:6379>

场景

状态统计

我们使用一个 online_statu用来存储 用户登录后的状态集合

如果1024用户登录系统,那么设置ID为1024的用户为在线的代码如下:

SETBIT online_statu 1024 1

如果想看1024的用户是否是在线状态(这边注意,key可能不存在,代表没有这个用户,这时候默认返回0),代码如下:

GETBIT online_statu 1024

如果1024的用户退出系统,则为他执行下线,代码如下:

SETBIT online_statu 1024 0

127.0.0.1:6379> SETBIT online_statu 1024 1
(integer) 0
127.0.0.1:6379> GETBIT online_statu 1024
(integer) 1
127.0.0.1:6379> SETBIT online_statu 1024 0
(integer) 1
127.0.0.1:6379>

空间上的有效利用,1亿 人的状态存储只需要 100000000/8/1024/1024 = 11.92 M,简单的数据结构也保证了性能上的优势。

根据实际的数据量获取存储空间:(offset/8/1024/1024)M

固定周期的签到情况统计(周/月/年)

固定周期可能是年/月/周,按照不同维度,可能有 365,31,7的bit位的统计周期。

假设这时候我们如果对于某个用户(如1024)全年的签到情况做统计,可以这么设计:

  • 设计key 为 {bus_type}{uid} ,及业务类型+用户id+年份

比如:sign_1024_2022

  • 签到则执行对应代码
  1. 1024用户在2022 年的第1天和最后一天如果有签到:
# 22年第一天
SETBIT sign_1024_2022 0 1# 22年最后一天
SETBIT sign_1024_2022 364 1
  1. 判断某用户(1024)在某一天(150)是否有签到
GETBIT sign_1024_2022 150
  1. 统计某用户(1024) 全面的签到次数,使用 BITCOUNT 指令,统计给定的 bit 数组中,值 = 1 的所有bit位数量。
BITCOUNT sign_1024_2022
  1. 那如果你想限定范围了怎么办,比如原来设计的是一年的统计。但是你想获得某个月第一次打卡的数据,这时候就要使用BITPOS了。
    通过 BITPOS key value [start] [end] 指令,返回数据表示 Bitmap 中第一个值为 给定value 的 offset 位置。
    在默认情况下,命令会检测整个位图,但用户也可以通过可选的start参数和end参数指定要检测的范围。
    比如第2个月的第3天是2月的第一次签到日,则下面的返回结果为30(第一个月31天)+ 3(二月第3天签到) = 33 :
$index = BITPOS sign_1024_2022 30

offset也是从0开始的,所以返回的值最好加个1,不会让用户看的晕头转向。

连续签到用户信息

  1. 可以把每天的日期当成位图(BitMap)的key,如 20251111;
  2. 用户的唯一键当成(UserId)当成offset,如编号 1024 的用户;
  3. 如果 1024 的用户在 2022.10.23 有签到,则位图的value为1,否则为0;

只有指定周期内的所有值都是1(签到)的时候,结果才是1,否则是我们整周或者整个月都拿起来【与】运算,得到的结果是不是1就能确是否满勤。

# 与运算:  0&0=0;0&1=0;1&0=0;1&1=1
# 下面为伪代码,类似:
(20221022 1024)  & ( 20221023 1024)  & ...

总结

1个byte等于8个bit,每个bit位只使用0或者1来表示,这样能够有效的降低存储空间,而Redis是存储在高速缓存中的,所以实际上是大大减少了内存占用。

很多场景都可以使用位图计算,比如我们上面说到的 是否登录、是否在线、是否签到、用户性别状态、IP黑名单、是否VIP用户统计 等等场景,但凡涉及到二值状态识别、海量统计的数据都可以考虑使用。

http://www.dtcms.com/a/592831.html

相关文章:

  • 基于web的养宠系统的实现2q26a2s2(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • Redis 底层运行机制与原理浅析
  • 中山做网站公司想做网站去哪里做
  • LeetCode算法刷题——49. 字母异位词分组
  • Spring Boot 常用注解全面解析:提升开发效率的利器
  • 《架构师修炼之路》——②对架构的基本认识
  • 基于GLM-4.6我做了一个智能口算天天练系统
  • 国外网站工作室自适应网站设计案例
  • 3.1 数据清洗与预处理
  • Docker 容器化部署 QINGLONG 面板指南
  • JQueryAjax
  • java格式化BigDecimal為#,###,##0.00
  • 增城建设网站济南seo排名优化推广
  • 用 Table ID 驯服异构库Flink CDC 跨系统表映射的工程化实践
  • 简洁大气的公司网站外包推广公司
  • MOSFET选型指南:为何ASIM阿赛姆是高效电源设计的优选
  • RV1126 NO.48:RV1126+OPENCV在视频中添加时间戳
  • Transformer实战(25)——自动超参数优化提升Transformer模型性能
  • 得实DS-300针式打印机使用连续纸打印完成后不能自动走到撕纸位置上怎么解决?
  • 大连网站建设在线win7如何做网站服务器
  • 怎样看一个网站做的网络广告郴州网络推广公司
  • 百度智能云 X 十字路口 | 对谈王雁鹏:亲述从大数据时代到 3 万卡集群的中国算力演进史
  • 初识MYSQL —— 索引
  • Blender快捷方式,自用Mark版
  • 移远 5G RG255AA-CN 调试
  • PyTorch3D从CUDA到CPU环境的完整迁移指南
  • 移动通信网络建设-实验2:5G站点选型与设备部署
  • 【自然语言处理】预训练06:子词嵌入
  • 地球的螺旋运动、四季轮回与椭圆轨道:统一场论下的宇宙新图景
  • html格式网站与网站开发有关的岗位是哪些