算法|基于Mysql5.7实现查找附近的店铺

【算法|基于Mysql5.7实现查找附近的店铺】我们新开发了一个电商平台,需要实现附近的店铺功能,经过预研,觉得没有必要采用mongodb的地理位置查询功能,因为涉及数据同步,还有联合索引的问题。直接用MySQL5.7内置的距离计算功能就可以满足大规模计算距离的需求。
计算附近的店铺时侯,一般的需求是传入用户的坐标,需要计算出附近的店铺,按照用户和店铺的距离排序返回前端。在成千上万家店铺选择附近的店铺就涉及效率的问题了。最好的方式是先找到附近的店铺,然后再在选定的店铺范围内计算距离,这样就能大幅减少计算量。业界采用的是geohash,首先在获取店铺坐标时候,就计算出店铺的geohash,在用户传入坐标后,也计算出用户的geohash和他周围8个区域的geohash,然后看店铺如果在用户周围的geohash范围内,才计算店铺和用户之间的距离。这里有个问题,如果用户在一个周围都是店铺的区域,那么检索的范围可能比较小就可以拿到用户每次翻页所请求店铺数了,但是如果用户在一个周围店铺不多的区域内,就需要检索一个比较大的范围才可以拿到用户每次翻页所请求的店铺数。这里就涉及geohash的精度问题了,geohash位数越高,所表示的范围越小,距离用户越近,反之越远。店铺需要预先计算一个精度比较高的geohash,如果想要取比较大的区域,只需要店铺的geohash like用户的geohash前几位就可以了.每次用户请求的时候,前端需要告诉后台用户的gps坐标,其他过滤条件,之前已经返回给用户的商铺id列表,后台按照用户的gps坐标按照7位精度计算出用户周围的9个geohash区域,加上过滤条件和不需要计算的店铺id列表,查询一下附近的店铺数,如果店铺数小于前端请求的数据条数的2倍(这里取2倍是考虑过的,假设店铺是平均分布的,用户的位置比较极端,恰好在他所在的geohash的角上,这样距离他比较近的点就在它周围的4个区域内,其他的5个区域的点离他都比较远,从区域的数量上来看是4:5,接近1:1吧,所以就选了2倍,应该差不多),就将计算的geohash列表的位数缩小一位,再去查询用户周围的店铺数,如果满足条件就退出,否则一直计算到4位精度,然后用最后拿到的geohash列表和过滤条件真正去计算用户周围的店铺和距离用户的距离,返回给前端.这样能最小化数据库计算和排序的压力.即使这样,作为数据库仍然是压力比较大的,在这里采用多从库可以解决并发的问题.至此,我们实现了基于Mysql5.7查找附近的店铺,计算量压缩到了极致,并发达到了无限.

    推荐阅读