geohash php_场景解决方案:附近的人(GeoHash的应用)

前言

附近的人,这四个字的需求就大有文章可做了。很二逼的做法是,存每个人的经度纬度,然后遍历数据库所有数据,foreach循环,两点距离坐标公式。量少的时候,这个没啥问题。量大了,扫描全表 + 经纬度距离运算分分钟拖垮数据库。那么是否有方案可以解决这个痛点呢,今年就来说下Geohash

实现思路

想要不拖垮数据,要做到能走索引。就是跟你无关的点,不要扫描。减少扫描行数来实现减轻数据库的压力。那么减少扫描行数肯定要想到索引。可是经纬度有两个字段,且查询条件无论怎么写都没办法走索引。那么唯一能想到的就是二维变一维。 geohash基本原理是将地球理解为一个二维平面,将平面递归分解成更小的子块,每个子块在一定经纬度范围内拥有相同的编码,这种方式简单粗暴,可以满足对小规模的数据进行经纬度的检索。两个点的距离越近,他们的编码前缀部分就相同,前缀部分相同越多,代表距离越近。然后我们做数据库扫描的时候 可以 WHERE geohash Like 'code%'这样就起到了走索引从而优化了执行效率。

代码思路(PHP)

class Geohash

{

const LATITUDE = 1;

const LONGITUDE = 2;

const BASE32 = array(

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',

'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm',

'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',

'y', 'z');

public static function encode($latitude = 0, $longitude = 0, $level = 11)

{

$latitude_str = self::separate($latitude, '', 1, self::get_precision_level_num($level, self::LATITUDE), self::get_interval_value(self::LATITUDE));

$longitude_str = self::separate($longitude, '', 1, self::get_precision_level_num($level, self::LONGITUDE), self::get_interval_value(self::LONGITUDE));

return self::geohash_encode(self::combination($latitude_str, $longitude_str));

}

public static

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值