在SQL数据库中存储纬度和经度数据时使用哪种数据types?

将纬度或经度数据存储在符合ANSI SQL的数据库中时,哪种数据types最合适? 应该使用float ,还是decimal ,还是…?

我知道Oracle,MySql和SQL Server已经添加了一些专门用于处理地理数据的特殊数据types,但是我对如何将信息存储在“普通的香草”SQL数据库中感兴趣。

Decimal(9,6)

如果你不习惯精确和缩放参数,这里是一个格式stringvisual:

###.######

我们使用浮点数,但任何数字与小数点后6位的味道也应该工作。

在vanilla Oracle中,称为LOCATOR(Spatial的残缺版本)的function要求使用NUMBER(无精度)的数据types来存储坐标数据。 当您尝试创build基于function的索引来支持空间查询时,它将会相反。

您可以很容易地将经纬度十进制数存储在一个无符号的整数字段中,而不是将它们分成整数和小数部分,并按照以下的build议使用以下转换algorithm单独存储:

作为一个存储的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 

这需要存储在一个无符号的int(10) ,这在mysql和sqlite中都是无types的。

通过经验,我发现这个工作真的很快,如果你只需要存储坐标和检索那些做一些math。

在PHP这2个function看起来像

 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; } 

这也有一些额外的优势,以及创build例如memcached唯一键与整数。 (例如:caching地理编码结果)。 希望这会增加讨论的价值。

另一个应用程序可能是当你没有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 */ 

我会用一个十进制数据的适当的精度。

我认为这取决于你最需要做的操作。

如果您需要将整个值作为十进制数,则使用具有适当精度和比例的十进制数。 我相信,浮动超出了你的需求。

如果你经常转换成degºmin'sec分数表示法,我会考虑将每个值存储为一个整数types(smallint,tinyint,tinyint,smallint?)。

那么,你问如何存储纬度/经度,我的回答是:不要,你可能会考虑使用WGS 84 (在欧洲ETRS 89 ),因为它是地理参考标准。

但是除了这个细节之外,我在SQL 2008之前的日子里使用了一个用户定义types,最终包含了地理支持。

你应该看看在SQL Server 2008中引入的新的Spatial数据types。它们是专门devise的这种types的任务,使索引和查询数据变得更容易和更高效。

http://msdn.microsoft.com/en-us/library/bb933876(v=sql.105).aspx

http://blogs.technet.com/andrew/archive/2007/11/26/sql-server-2008-spatial-data-types.aspx