Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 近距离搜索_Php_Mysql_Proximity - Fatal编程技术网

Php 近距离搜索

Php 近距离搜索,php,mysql,proximity,Php,Mysql,Proximity,应用程序如何执行邻近搜索?例如,用户键入邮政编码,然后应用程序列出20英里内按邻近性排序的所有企业 我想在PHP和MySQL中构建类似的东西。这种方法正确吗 获取我感兴趣的位置的地址并存储在我的数据库中 使用谷歌的地理编码服务对所有地址进行地理编码 编写一个包含Haversine公式的数据库查询,以进行近似搜索和排序 这样行吗?在步骤3中,我将计算每个查询的接近度。是否最好有一个近似表,列出每家企业与几个参考地点之间的距离?如果有足够的记录说明速度的重要性,这里有一种提前索引它们的方法 定义一个

应用程序如何执行邻近搜索?例如,用户键入邮政编码,然后应用程序列出20英里内按邻近性排序的所有企业

我想在PHP和MySQL中构建类似的东西。这种方法正确吗

  • 获取我感兴趣的位置的地址并存储在我的数据库中
  • 使用谷歌的地理编码服务对所有地址进行地理编码
  • 编写一个包含Haversine公式的数据库查询,以进行近似搜索和排序

  • 这样行吗?在步骤3中,我将计算每个查询的接近度。是否最好有一个近似表,列出每家企业与几个参考地点之间的距离?

    如果有足够的记录说明速度的重要性,这里有一种提前索引它们的方法


    定义一个侧面约20英里的垃圾箱网格。将箱子编号与每个商店的记录一起存储。在搜索时,计算与搜索点相交20英里半径的所有垃圾箱的数量。然后检索这些存储箱中的所有存储,并像以前一样继续操作。

    我们对大约1200个位置执行此操作。我会即时使用Haversine公式,尽管根据应用程序的不同,最好将其存储在PHP中而不是SQL中。(我们的实现是在.net中实现的,因此您的差异可能会有所不同)

    实际上,我们实现它的方式的最大缺点是,每次计算(直到最近)都必须在数据层上进行,这是非常缓慢的(当我说慢的时候,我的意思是非即时的,它需要一秒钟左右),但这是因为它必须根据提供的邮政编码计算所有1200个地点的距离

    根据您选择的路线,可以通过查看经度和纬度并删除预定义范围之外的经度和纬度来加快数字距离计算(例如,如果您正在查看20英里内的所有地址,则可以计算出20英里以外的所有地址的经度范围。)如果需要,可以加快查询速度


    实际上,我们考虑了在数据库中存储所有可能的组合。实际上,听起来它可能是一个大型数据存储,但实际上它不在大范围内。有了索引,它可以非常快,而且你不必担心算法优化等。我们决定不使用它,因为我们有C#中的等式,而且它是允许我们缓存在业务层中执行所有计算所需的信息。两者都可以正常工作,这只是您的偏好问题。

    我们使用它来执行数千个点。如果您在SQL中执行此操作,则在纬度和经度列上建立索引非常重要。我们尝试在SQL 2008使用空间索引,但我们确实没有看到预期的性能提高。不过,如果要在距离邮政编码一定距离内进行计算,则需要考虑是否要使用邮政编码的邮政编码形心或多边形表示

    这是一个很好的开始

    我们在动态计算距离时没有遇到性能问题,对于某些应用程序,我们会提前计算距离,因为我们提前知道点,并且会有数百万条记录

    SELECT
            [DistanceRadius]=
            69.09 *
            DEGREES(
              ACOS(
                SIN( RADIANS(latitude) )*SIN( RADIANS(@ziplat) ) 
               +
                COS( RADIANS(latitude) )*COS( RADIANS(@ziplat) ) 
               *
                COS( RADIANS(longitude - (@ziplon)) )
              )
            )
            ,*
            FROM
                table
    
        ) sub
    WHERE
        sub.DistanceRadius < @radius
    
    选择
    [距离半径]=
    69.09 *
    学位(
    ACOS(
    SIN(弧度(纬度))*SIN(弧度(@ziplat))
    +
    COS(弧度(纬度))*COS(弧度(@ziplat))
    *
    COS(弧度(经度-(@ziplon)))
    )
    )
    ,*
    从…起
    桌子
    )潜艇
    哪里
    子距离半径<@半径
    
    另请参见罚款