Skip to main content

特殊类型

David LiuAbout 6 min

特殊类型

Bitmap

底层String 类型是会保存为二进制的字节数组

介绍

Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 Bitmap 本身会极大的节省储存空间。

你可以将 Bitmap 看作是一个存储二进制数字(0 和 1)的数组,数组中每个元素的下标叫做 offset(偏移量)。

命令

  • SETBIT
  • GETBIT
  • BITCOUNT
  • BITOP
  • BITPOS

应用

需要保存状态信息(0/1 即可表示)的场景

  • 举例 :用户签到情况、活跃用户情况、用户行为统计(比如是否点赞过某个视频)。
判断用户登陆态

Bitmap 提供了 GETBIT、SETBIT 操作,通过一个偏移值 offset 对 bit 数组的 offset 位置的 bit 位进行读写操作,需要注意的是 offset 从 0 开始。

只需要一个 key = login_status 表示存储用户登陆状态集合数据, 将用户 ID 作为 offset,在线就设置为 1,下线设置 0。通过 GETBIT判断对应的用户是否在线。 5000 万用户只需要 6 MB 的空间。

HyperLogLog

HyperLogLog 的实现涉及到很多数学问题,太费脑子了,我也没有搞懂,如果你想了解一下,课下可以看看这个:HyperLogLog (opens new window)open in new window

命令

  • PFADD
  • PFCOUNT
  • PFMERGE

应用

数量量巨大(百万、千万级别以上)的计数场景

  • 举例 :热门网站每日/每周/每月访问 ip 数统计、热门帖子 uv 统计、

GEO

Geospatial index(地理空间索引,简称 GEO),基于 Sorted Set 实现。

原理 - GEOHash

Redis 的 GEOHash 是一种基于经纬度的地理位置索引算法,它将地球表面的经纬度坐标转换为一个字符串,这个字符串可以用于快速地计算两个地理位置之间的距离和排序。

GEOHash 算法的原理是将地球表面的经纬度坐标转换为一个二进制编码,然后将这个编码转换为一个字符串。具体来说,GEOHash 算法将地球表面的经度和纬度分别划分为若干个区间,然后将每个区间编码为一个二进制位,最终将所有二进制位拼接起来,得到一个二进制编码。这个二进制编码可以转换为一个字符串,这个字符串就是 GEOHash 算法的输出结果。

在 Redis 中,GEOHash 算法被用于实现地理位置索引,具体来说,Redis 将每个地理位置转换为一个 GEOHash 字符串,并将这个字符串作为键,将地理位置的信息作为值存储在哈希表中。这样,就可以通过 GEOHash 字符串快速地查找附近的地理位置,计算两个地理位置之间的距离等。

GEOHash 算法的优点是计算简单、存储空间小、查询速度快,但是也存在一些缺点,例如精度不高、距离计算不准确等。为了解决这些问题,可以采用一些改进的算法,例如 GeoHash+、GeoHash+、GeoMesa 等。

GEO 类型使用 GeoHash 编码方法实现了经纬度到 Sorted Set 中元素权重分数的转换,这其中的两个关键机制就是「对二维地图做区间划分」和「对区间进行编码」。一组经纬度落在某个区间后,就用区间的编码值来表示,并把编码值作为 Sorted Set 元素的权重分数。

当将空间划分为四块时候,编码的顺序分别是左下角00,左上角01,右下脚10,右上角11,也就是类似于Z的曲线。当我们递归的将各个块分解成更小的子块时可以标识更小的空间范围(如上图二中所示),如从0000开始到1111结束编码的顺序是自相似的(分形),每一个子快也形成Z曲线,这种类型的曲线被称为Peano空间填充曲线

Geohash 通过将节点数据编码转换成一维数据,(base 32 和 base 36) 会将落到网格中的二进制数据编码成字符串,再使用B树索引快速查找出需要的数据。

*2. 注意点*

我们已经知道现有的 GeoHash 算法使用的是 Peano 空间填充曲线,这种曲线会产生突变,造成了编码虽然相似但距离可能相差很大的问题,因此在查询附近餐馆时候,首先筛选GeoHash编码**「相似的POI(point of interest)点」**,然后进行实际距离计算。

*3. 使用心得*

GeoHash 只是空间索引的一种方式,特别适合点数据,而对**「线、面数据采用R树索引」**更有优势(可为什么需要空间索引)。

GeoHash值可以区分精度,位数越多,精度越高,表达的地理位置越精细;如一位的GeoHash值把地球划分为32个矩形,8位的geohash值把地球划分为32^8个小矩形

适合根据某个经纬度坐标position计算出GeoHash值,然后和数据库中精度更高的GeoHash值做前缀比较

命令

  • GEOADD
  • GEOPOS
  • GEODIST
  • GEORADIUS

Redis的GEO结构是一种用于存储地理位置信息的数据结构,它可以将经纬度坐标和其他相关信息存储在一个有序集合中。以下是一些常用的GEO指令及其用法:

  1. GEOADD:将一个或多个成员添加到指定的GEO集合中。
GEOADD {{key}} {{longitude}} {{latitude}} {{member}} [{{longitude}} {{latitude}} {{member}} ...]

示例:

GEOADD cities 13.361389 38.115556 "Rome" 15.087269 37.502669 "Athens" -122.419416 37.774929 "San Francisco"
  1. GEODIST:计算两个成员之间的距离。
GEODIST {{key}} {{member1}} {{member2}} [m|km|ft|mi]

示例:

GEODIST cities Rome Athens km
  1. GEOHASH:获取一个或多个成员的geohash值。
GEOHASH {{key}} {{member}} [{{member}} ...]

示例:

GEOHASH cities Rome Athens
  1. GEOPOS:获取一个或多个成员的经纬度坐标。
GEOPOS {{key}} {{member}} [{{member}} ...]

示例:

GEOPOS cities Rome Athens
  1. GEORADIUS:获取指定坐标范围内的成员。
GEORADIUS {{key}} {{longitude}} {{latitude}} {{radius}} [m|km|ft|mi] [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT {{count}}]

示例:

GEORADIUS cities 15.087269 37.502669 200 km WITHDIST
  1. GEORADIUSBYMEMBER:获取指定成员范围内的成员。
GEORADIUSBYMEMBER {{key}} {{member}} {{radius}} [m|km|ft|mi] [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT {{count}}]

示例:

GEORADIUSBYMEMBER cities Rome 200 km WITHCOORD

以上是一些常用的GEO指令及其用法,更多指令可以参考Redis官方文档。

应用

需要管理使用地理空间数据的场景

  • 举例:附近的人。

Stream

5.0 新增