您可以轻松地将纬度/经度十进制数存储在无符号整数字段中,而不是将它们拆分为整数和小数部分,然后使用以下转换算法将它们分开存储:
作为存储的mysql函数:
CREATE DEFINER=`r`@`l` FUNCTION `PositionSmallToFloat`(s INT)
RETURNS decimal(10,7)
DETERMINISTIC
RETURN if( ((s > 0) && (s >> 31)) , (-(0x7FFFFFFF -
(s & 0x7FFFFFFF))) / 600000, s / 600000)
返回
CREATE DEFINER=`r`@`l` FUNCTION `PositionFloatToSmall`(s DECIMAL(10,7))
RETURNS int(10)
DETERMINISTIC
RETURN s * 600000
这需要存储在 unsigned int(10) 中,这适用于 mysql 以及无类型的 sqlite。
根据经验,我发现它的运行速度非常快,如果您只需要存储坐标并检索这些坐标以进行数学运算。
在 php 中这两个函数看起来像
function LatitudeSmallToFloat($LatitudeSmall){
if(($LatitudeSmall>0)&&($LatitudeSmall>>31))
$LatitudeSmall=-(0x7FFFFFFF-($LatitudeSmall&0x7FFFFFFF))-1;
return (float)$LatitudeSmall/(float)600000;
}
又回来了:
function LatitudeFloatToSmall($LatitudeFloat){
$Latitude=round((float)$LatitudeFloat*(float)600000);
if($Latitude<0) $Latitude+=0xFFFFFFFF;
return $Latitude;
}
这在创建例如带有整数的 memcached 唯一键方面也有一些额外的优势。 (例如:缓存地理编码结果)。希望这能为讨论增加价值。
另一个应用程序可能是当您没有 GIS 扩展并且只想保留几百万个纬度/经度对时,您可以在 mysql 中的这些字段上使用分区以受益于它们是整数的事实:
Create Table: CREATE TABLE `Locations` (
`lat` int(10) unsigned NOT NULL,
`lon` int(10) unsigned NOT NULL,
`location` text,
PRIMARY KEY (`lat`,`lon`) USING BTREE,
KEY `index_location` (`locationText`(30))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY ()
PARTITIONS 100 */