我想知道你的意见。我创建了一个应用程序,用户在其中创建路径并跟踪此路径并保存数据库中的所有路径点。然后,应用程序会对用户路点进行比较。
目前,我使用MSSQL
服务器,使用两个表,一个用于路由,另一个用于存储路点(具有空间数据类型)。使用SQL Server地理函数(如st_distance ...
我调查了其他选项。我实现的是使用对象的Oracle 11g。我将所有数据仅存储在一个对象表中,并将点的方式存储在具有纬度和经度属性的类型的Varray中。这种方式可以非常有效地保存和检索数据,但在比较时会变得复杂。
我正在寻找一个NoSQL
解决方案,一些算法或方法来有效地完成这项工作。你觉得怎么样?
答案 0 :(得分:15)
对所有n条记录使用STDistance等数据库函数是次优的。您的CPU开销将呈指数级增长。
您应该检查当前正在搜索的震中周围的矩形内的点数。这是一个例子(在MySQL中):
SELECT * FROM `points`
WHERE `latitude` >= X1 AND `latitude` <= X2
AND `longitude` >= Y1 AND `longitude` <= Y2
这提供了一个减少的superset
个点,然后通过使用Haversine formula计算顺向距离(相对于地球的曲率)来进一步减少。
不要忘记在latitude
和longitude
上设置composite index。
这是PHP:
<?php
function haversine($latitude1, $longitude1,
$latitude2, $longitude2, $unit = 'Mi') {
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) +
(cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch ($unit) {
case 'Mi':
break;
case 'Km':
$distance = $distance * 1.609344;
}
return (round($distance, 2));
}
?>
回顾:
这是一个示例图片,说明了该做什么:
第一次搜索将涉及边界框碰撞搜索(MySQL示例)以确定superset
,不包括红点。第二个验证过程将涉及使用Haversine公式(PHP示例)计算点是否在适当的顺向距离内,并采用subset
(由黑点组成)。