Redis从入门到放弃(4):3种新数据类型
1、介绍
前面的文章已经介绍了redis的5种基本数据类型,redis6中另外还有3种特殊的数据类型,分别是 Bitmaps (位图)、HyperLogLogs(基数统计)和 geospatial (地理位置)。本文将继续探讨它们的特性、原理以及应用场景。
2、 Bitmaps(位图)
Bitmaps是一种位图数据结构,用于存储位的集合。在Redis中,Bitmaps通常用于表示一系列元素的状态,每个元素用一个位来表示,位的值为0或1。
2.1、特性
- 空间效率:Bitmaps使用非常少的内存来存储数据,适用于大规模数据的位集合操作。
- 高效的位运算:Bitmaps支持位运算,如AND、OR、XOR等,可以快速地对位集合进行操作。
2.2、原理
Bitmaps的底层数据结构是一个二进制位数组,其中的每一个位都只能存储0或1。通过对位数组进行操作,可以实现集合成员的添加、删除和查询。
示例:假设我们有一个用户状态的Bitmaps,每个用户用一个位表示,1表示在线,0表示离线。

SETBIT key offset value
#设置offset偏移位的值为value,offset的值是从0开始的,n代表第n+1个bit位置的。
#offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。
#value 的值只能为0或1
#返回值:指定偏移量原来储存的位。
# 设置用户1为在线状态
SETBIT online_users 1 1
# 设置用户2为离线状态
SETBIT online_users 2 0
# 查询用户1的状态
GETBIT online_users 1 # 返回 1 (在线)
# 查询用户3的状态
GETBIT online_users 3 # 返回 0 (离线)
# 获取在线用户数量
BITCOUNT online_users # 返回 2 (有两个用户在线)
2.3、应用场景
- 用户在线状态:可以用Bitmaps来表示用户是否在线,每个位代表一个用户,1表示在线,0表示离线。
- 统计功能:通过位运算可以实现多个集合的交集、并集等操作,适用于一些统计功能的实现。
2.4、代码
import redis.clients.jedis.Jedis;
public class RedisBitmapsDemo {
public static void main(String[] args) {
// 连接到Redis服务器
Jedis jedis = new Jedis("localhost");
// 设置用户1为在线状态
jedis.setbit("online_users", 1, true);
// 设置用户2为在线状态
jedis.setbit("online_users", 2, true);
// 查询用户1的状态
boolean isUser1Online = jedis.getbit("online_users", 1);
System.out.println("用户1是否在线:" + isUser1Online);
// 查询用户3的状态
boolean isUser3Online = jedis.getbit("online_users", 3);
System.out.println("用户3是否在线:" + isUser3Online);
// 获取在线用户数量
long onlineUserCount = jedis.bitcount("online_users");
System.out.println("在线用户数量:" + onlineUserCount);
// 关闭连接
jedis.close();
}
}
3、 HyperLogLog(基数统计)
什么是基数?
举个例子,A = {1, 2, 3, 4, 5}, B = {3, 5, 6, 7, 9};那么基数(不重复的元素)= 1, 2, 4, 6, 7, 9; (允许容错,即可以接受一定误差)
HyperLogLog是一种用于基数统计(即集合中不同元素的数量)的数据结构。它可以用来估计一个集合中不同元素的数量,而不需要存储每个元素的具体值。HyperLogLog的优势在于其内存占用非常小,同时可以提供较高的近似精确度。
3.1、特性
- 高效的内存利用:HyperLogLog使用固定大小的内存来存储集合的近似基数,无论集合大小如何,内存占用都相对固定。
- 近似精确度:HyperLogLog虽然是近似计数,但对于大部分数据集合,可以提供较高的准确度。
3.2、原理
HyperLogLog通过使用一组哈希函数来统计集合中不同元素的数量。对于每个元素,首先使用哈希函数对其进行哈希,然后找到哈希值中最高位的1所在的位置。最后根据最高位1的位置来估计集合的基数。
示例:统计一组用户的唯一访问次数。
# 添加用户的访问记录
PFADD user_visits user1
PFADD user_visits user2
PFADD user_visits user1
# 查询唯一访问次数
PFCOUNT user_visits # 返回 2 (有两个用户的唯一访问记录)
3.3、应用场景
- 统计UV:在网站统计中,如果需要统计不同用户(UV)的数量,可以使用HyperLogLog来估计UV的数量,从而减少内存占用。
- 数据流中的去重:在数据流中,如果需要实时去重并统计不同元素的数量,可以使用HyperLogLog来估计去重后的元素数量。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog 不能像集合那样,返回输入的各个元素。
3.4、代码
import redis.clients.jedis.Jedis;
public class RedisHyperLogLogDemo {
public static void main(String[] args) {
// 连接到Redis服务器
Jedis jedis = new Jedis("localhost");
// 添加用户的访问记录
jedis.pfadd("user_visits", "user1");
jedis.pfadd("user_visits", "user2");
jedis.pfadd("user_visits", "user1");
// 查询唯一访问次数
long uniqueVisits = jedis.pfcount("user_visits");
System.out.println("唯一访问次数:" + uniqueVisits);
// 关闭连接
jedis.close();
}
}
4、Geospatial(地理位置)
Geospatial是一种地理空间数据结构,用于存储地理位置的信息。在Redis中,Geospatial使用了基于Z字形扫描的算法,可以高效地存储和查询地理位置信息。
4.1、特性
- 高效的地理位置查询:Geospatial支持在给定的地理位置半径范围内查询其他地理位置点,例如查询附近的商店、用户等。
- 可以存储附加信息:除了地理位置信息,Geospatial还可以存储附加的信息,如商店的名称、用户的ID等。
4.2、原理
Geospatial使用一个二维空间索引来存储地理位置信息,利用Z字形扫描算法可以快速地查询附近的地理位置点。
示例:存储商店的地理位置信息和名称。
# 添加商店的地理位置信息和名称
GEOADD stores 116.4039 39.9149 "Shop A"
GEOADD stores 116.3372 39.9218 "Shop B"
GEOADD stores 116.3525 39.9138 "Shop C"
# 查询附近的商店
GEORADIUS stores 116.4000 39.9100 500 m WITHCOORD COUNT 2
4.3、应用场景
- 附近的人:在社交应用中,可以使用Geospatial来查找附近的用户,以实现附近的人功能。
- 地理位置签到:可以使用Geospatial来实现地理位置签到功能,记录用户在特定地点的签到信息。
4.4、代码
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
import java.util.List;
public class RedisGeospatialDemo {
public static void main(String[] args) {
// 连接到Redis服务器
Jedis jedis = new Jedis("localhost");
// 添加商店的地理位置信息和名称
jedis.geoadd("stores", 116.4039, 39.9149, "Shop A");
jedis.geoadd("stores", 116.3372, 39.9218, "Shop B");
jedis.geoadd("stores", 116.3525, 39.9138, "Shop C");
// 查询附近的商店
double longitude = 116.4000;
double latitude = 39.9100;
double radius = 500; // 半径500米
List<GeoRadiusResponse> nearbyStores = jedis.georadius("stores", longitude, latitude, radius, GeoUnit.M);
for (GeoRadiusResponse store : nearbyStores) {
String storeName = store.getMemberByString();
GeoCoordinate coordinates = store.getCoordinate();
double distance = store.getDistance();
System.out.println("附近商店:" + storeName + ",经度:" + coordinates.getLongitude() + ",纬度:" + coordinates.getLatitude() + ",距离:" + distance + "米");
}
// 关闭连接
jedis.close();
}
}
5、总结
Redis6引入了三种新的数据类型:Bitmaps、HyperLogLog和Geospatial,这些新数据类型为Redis提供了更多灵活的功能和应用场景。Bitmaps适用于大规模数据的位集合操作,HyperLogLog用于近似统计集合的基数,而Geospatial则用于高效存储和查询地理位置信息。通过合理的使用这些新数据类型,可以让Redis在更多场景下发挥出强大的性能和功能。
Redis从入门到放弃(4):3种新数据类型的更多相关文章
- Redis 从入门到放弃
Redis 从入门到放弃 http://www.iocoder.cn/Fight/Redis-went-from-getting-started-to-quitting/
- Redis(二)redis发布与订阅以及三种新数据类型
1 配置文件 Utis单位部分 redis支持字节但不支持其他类型 Includes部分 设置包含的其他文件的目录 netword网络部分 bind:默认情况bind=127.0.0.1只接受本机的访 ...
- Redis6通信协议升级至RESP3,一口气看完13种新数据类型
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 在前面的文章 Redis:我是如何与客户端进行通信的 中,我们介绍过RESP V2版本协议的规范,RESP的全程是Redis Serializa ...
- redis从入门到放弃 -> 部署方案
单点部署方案 环境准备: [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@ ...
- redis从入门到放弃 -> 简介&概念
一.redis简介 Redis是一款开源的.高性能的键-值存储.它常被称作是一款数据结构服务器. 当值支持的主要数据类型为:字符串(strings)类型,括哈希(hashes).列表(lists).集 ...
- Redis——从入门到放弃
redis简介 Redis is an open source (BSD licensed), in-memory data structure store, used as a database, ...
- Redis入门到放弃系列-redis数据类型
Redis数据类型? Redis 提供一些常用的数据类型:Strings.Lists.Sets.Sorted sets.Hashes.Arrays.Bitmap.Streams Strings(字符串 ...
- Scrapy入门到放弃01:开启爬虫2.0时代
前言 Scrapy is coming!! 在写了七篇爬虫基础文章之后,终于写到心心念念的Scrapy了.Scrapy开启了爬虫2.0的时代,让爬虫以一种崭新的形式呈现在开发者面前. 在18年实习的时 ...
- OpenStack从入门到放弃
OpenStack从入门到放弃 目录: 为何选择云计算/云计算之前遇到的问题 什么是云计算 云服务模式 云应用形式 传统应用与云感知应用 openstack及其相关组件介绍 flat/vlan/gre ...
- 超强、超详细Redis数据库入门教程
这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...
随机推荐
- rockyLinux 初体验(教程)PostgreSQL15
目录 数据库软件 PostgreSQL 安装 数据库软件 PostgreSQL 配置 数据库软件 PostgreSQL 交互 通用数据库管理软件 DBeaver 彼时,PostgreSQL 已经更新到 ...
- Django笔记三十一之全局异常处理
本文首发于公众号:Hunter后端 原文链接:Django笔记三十一之全局异常处理 这一篇笔记介绍 Django 的全局异常处理. 当我们在处理一个 request 请求时,会尽可能的对接口数据的格式 ...
- 音视频八股文(3)--ffmpeg常见命令(2)
07-ffplay命令播放媒体 播放本地文件 播放本地 MP4 视频文件 test.mp4 的命令,从第 2 秒位置开始播放,播放时长为 10 秒,并且在窗口标题中显示 "test time ...
- 2021-12-31:给定一个arr,里面的数字都是0~9, 你可以随意使用arr中的数字,哪怕打乱顺序也行, 请拼出一个能被3整除的,最大的数字,用str形式返回。 来自去哪儿网。
2021-12-31:给定一个arr,里面的数字都是0~9, 你可以随意使用arr中的数字,哪怕打乱顺序也行, 请拼出一个能被3整除的,最大的数字,用str形式返回. 来自去哪儿网. 答案2021-1 ...
- Python encode()方法和decode()方法
Python encode()方法 encode() 方法为字符串类型(str)提供的方法,用于将 str 类型转换成 bytes 类型,这个过程也称为"编码".encode() ...
- ModuleNotFoundError: No module named 'flask_sqlalchemy'
ModuleNotFoundError: No module named 'flask_sqlalchemy' 解决: pip install flask_sqlalchemy
- Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.
问题描述 新建表或者修改表varchar字段长度的时候,出现这个错误 Row size too large. The maximum row size for the used table type, ...
- 去掉谷歌/新版Edge 浏览器的禁用扩展提示
简介 你打开是谷歌/新版Edge浏览器的时候是不是总发现右上角有个提示?请禁用/停用以开发者模式运行的扩展程序?每次打开都有一个小框框,让人很烦? 接下来让我们使用 dll大法 来解决这个问题! 步骤 ...
- Bash 编程
原文:https://seankross.com/the-unix-workbench/bash-programming.html[1] 数学 创建math.sh: #!/usr/bin/env ba ...
- 今天在内部 Galaxy 分析平台操作探针引物设计小工具程序,调用 Ensembl API 获取相关序列和信息时,发现官网 MySQL server 异常,报告问题后当天晚上就收到了回复,并且修......
本文分享自微信公众号 - 生信科技爱好者(bioitee).如有侵权,请联系 support@oschina.cn 删除.本文参与"OSC源创计划",欢迎正在阅读的你也加入,一起分 ...