Redis GeoHash 详解
Redis 提供了 Geo(地理位置) 模块,其中 GeoHash 是一种用于存储和查询地理位置信息的数据结构。它能够高效地进行地理位置存储、查询、计算距离和查找附近地点等操作。
1. 什么是 GeoHash?
GeoHash 是一种将经纬度坐标转换为字符串编码的方式,它具有:
- 空间映射:将 2D 坐标(纬度 + 经度) 转换成 1D 字符串。
- 前缀匹配:相邻的地点会有相似的编码 (前缀相同,位置接近)。
- 高效存储:只需用短字符串表示一个地点,减少存储空间。
- 快速查询:可以基于 GeoHash 前缀进行快速附近查找。
2. Redis GeoHash 存储结构
Redis 的 Geo 采用 Sorted Set(有序集合) 来存储地理位置信息:
- Member(成员):地点名称(如
restaurant_1
)。 - Score(分数):经纬度被编码为 52 位整数,作为排序依据。
3. Redis Geo 常用命令
(1)GEOADD:添加地理位置
语法
GEOADD key longitude latitude member
示例
GEOADD cities 116.40 39.90 "Beijing"
GEOADD cities 121.47 31.23 "Shanghai"
GEOADD cities 114.05 22.54 "Shenzhen"
📌 作用:将 Beijing
、Shanghai
和 Shenzhen
的经纬度存入 cities
集合中。
(2)GEOPOS:获取存储的经纬度
语法
GEOPOS key member [member ...]
示例
GEOPOS cities "Beijing" "Shanghai"
📌 返回
[[116.40, 39.90], // 北京[121.47, 31.23] // 上海
]
(3)GEODIST:计算两点距离
语法
GEODIST key member1 member2 [unit]
- 单位(unit):
m
(米)km
(千米)mi
(英里)ft
(英尺)
示例
GEODIST cities "Beijing" "Shanghai" km
📌 返回
1067.5711
表示 北京到上海直线距离 ≈ 1067.57 km。
(4)GEORADIUS(已废弃) & GEOSEARCH:查找附近地点
⚠️ Redis 6.2 以后,
GEORADIUS
被GEOSEARCH
取代!
🔹 使用 GEOSEARCH
语法
GEOSEARCH key FROMMEMBER member BYRADIUS radius unit
示例:查找北京 1000 km 内的城市
GEOSEARCH cities FROMMEMBER "Beijing" BYRADIUS 1000 km
📌 返回
1) "Beijing"
2) "Shanghai"
🔹 使用 GEOSEARCHSTORE
存储结果
GEOSEARCHSTORE nearby_cities cities FROMMEMBER "Beijing" BYRADIUS 1000 km
📌 作用:将 Beijing
附近 1000 km 内的城市 存入 nearby_cities
集合。
(5)GEOHASH:获取 GeoHash 编码
语法
GEOHASH key member [member ...]
示例
GEOHASH cities "Beijing" "Shanghai"
📌 返回
1) "wx4g09z"
2) "wtw3sj5"
解析:
- “wx4g09z” 代表 北京 的 GeoHash 编码
- “wtw3sj5” 代表 上海 的 GeoHash 编码
💡 GeoHash 编码规则:
- 编码越长,精度越高
- 相邻位置的前缀相似
- 可以用前缀匹配进行快速区域查询
4. GeoHash 的工作原理
(1)GeoHash 编码过程
- 将经纬度分别转换成二进制
- 纬度
[-90, 90]
→ 变成0 ~ 1
- 经度
[-180, 180]
→ 变成0 ~ 1
- 纬度
- 交错合并 纬度 + 经度
- 转换为 Base32 字符串
Base32
编码使用 “0123456789bcdefghjkmnpqrstuvwxyz” 这 32 个字符。
(2)GeoHash 编码精度
GeoHash 长度 | 经纬度误差范围 |
---|---|
1 字符 | ± 5,000 km |
2 字符 | ± 1,250 km |
3 字符 | ± 156 km |
4 字符 | ± 39 km |
5 字符 | ± 4.9 km |
6 字符 | ± 1.2 km |
7 字符 | ± 152 m |
8 字符 | ± 19 m |
📌 示例
"wx4g09z"
→ 代表 北京"wx4g"
→ 代表北京的 大范围"wx4"
→ 代表北京的 省级范围
5. Redis GeoHash 适用场景
✅ LBS(位置服务)
- 查找附近的商家、外卖、快递配送点
- 查找附近的用户(如社交软件)
✅ 共享出行
- 计算司机与乘客的距离
- 查找最近的车辆
✅ 物流配送
- 计算配送范围
- 规划最优配送路径
✅ 线下商店推荐
- 查找最近的门店
6. Redis Geo vs. 其他存储方式
方式 | 优势 | 劣势 |
---|---|---|
Redis GeoHash | 存储简单,查询速度快 | 精度受 GeoHash 影响,适用于近似范围查询 |
MySQL Geography | 计算精准,支持 ST_Distance | 查询慢,存储复杂 |
PostGIS | 支持复杂 GIS 操作 | 需要额外数据库 |
H3(Uber 开源) | 多级网格切割,支持全球计算 | 需要额外库,复杂度较高 |
7. 总结
✅ Redis GeoHash 通过 Sorted Set 存储地理位置数据,支持快速查询和计算距离。
✅ 常用命令:
GEOADD
(添加地点)GEOPOS
(获取经纬度)GEODIST
(计算两点距离)GEOSEARCH
(查找附近地点)GEOHASH
(获取 GeoHash 编码)
💡 适用于 LBS、物流、共享出行、门店推荐等场景,查询速度快,内存占用少!