mysql查看用户(还在用MySQL计算用户距离吗)

背景

在review同事代码时,看到了一个很长的SQL,功能是为用户找到附近的100个店铺。我忍不住提出了一种更优雅更快捷的方式:利用redis 的一种在Redis3.2版本中推出高级数据类型GEO(不要再说Redis只有5种数据结构了),特别是数据量比较大时,效率高于MySQL很多。

mysql查看用户(还在用MySQL计算用户距离吗)(1)

mysql 计算经纬度

简介

Redis的GEO可以将用户给定的地理位置(经度和纬度)信息储存起来,并对这些信息进行操作。GEO相关命令只有6个:

mysql查看用户(还在用MySQL计算用户距离吗)(2)

改进思路

  1. 将店铺信息存储在Redis中
  2. 利用Redis的GEORADIUS 查出附近的10个店铺

springboot redis实战

引入jar包

mysql查看用户(还在用MySQL计算用户距离吗)(3)

利用StringRedisTemplate API

mysql查看用户(还在用MySQL计算用户距离吗)(4)

mysql查看用户(还在用MySQL计算用户距离吗)(5)

测试结果

redis计算

mysql查看用户(还在用MySQL计算用户距离吗)(6)

MySQL计算

mysql查看用户(还在用MySQL计算用户距离吗)(7)

结论: 可见2个的结果一致。

也说原理

我们知道经度范围(-180,180),纬度范围(-90,90)。

以纬度为例,用二分法将纬度(-90,90)分成两个区间,(-90,0)和(0,90),如果目标纬度落在左边区间则记为0,否则记为1;再将目标纬度所在的那个区间再通过二分法分成两个相等的区间,如果目标纬度落在左边区间则记为0,否则记为1,以此类推,可以得到一个二进制数。同理经度也以此可以推导出一个二进制数。

假如得到的经纬度二进制数如下

经度:110101100101001110111100011010 纬度:101011000101010000110101100101

然后通过偶数位放经度,奇数位放纬度将经纬度合并,从0位开始数起(0是偶数位,放经度)

结果

111001100111100000110011000110101000111110110001011010011001

然后按照从左往右,每n位划分成1个组(n 越小越精确)

假如n为5,则结果

11100 11001 11100 00011 00110 00110 10100 01111 10110 00101 10100 11001

换成十进制,

28 25 28 3 6 6 20 15 22 5 20 25

然后十进制转base32字符串:4Z4CGGUPWFUZ

如果有另外一个经纬度转化后为:4Z4CGGUPWFUA,则两个字符串能匹配11位,比较相似,距离就比较近。

mysql查看用户(还在用MySQL计算用户距离吗)(8)

演示视频

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。