当在符合ANSI SQL的数据库中存储纬度或经度数据时,哪种数据类型最合适?应该使用float
还是decimal
或...?
[我知道Oracle,MySql和SQL Server添加了一些专门用于处理地理数据的特殊数据类型,但是我对您如何将信息存储在“普通香草” SQL数据库中感兴趣。
对于经度使用:Decimal(9,6)
,而纬度使用:Decimal(8,6)
如果您不习惯精确度和缩放参数,请使用以下格式的字符串:
[###.######
和##.######
我们使用浮点数,但任何具有6位小数位的数字形式也应适用。
[在香草Oracle中,称为LOCATOR(Spatial的残废版本)的功能要求使用NUMBER(无精度)的数据类型存储坐标数据。当您尝试创建基于函数的索引以支持空间查询时,它会堵住其他情况。
您可以轻松地将经纬度十进制数字存储在无符号整数字段中,而不是将它们分成整数和小数部分,然后使用以下转换算法将它们分开存储(如此处所建议的那样:]
作为存储的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;
}
这在创建例如带有整数的内存缓存唯一键方面也具有一些额外的优势。 (例如:缓存地址解析结果)。希望这能增加讨论的价值。
另一个应用程序可能是当您没有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“分数表示法,我会考虑将每个值存储为整数类型(smallint,tinyint,tinyint,smallint?)。
您应该看一下SQL Server 2008中引入的新Spatial数据类型。它们是为此类任务专门设计的,它使索引和查询数据变得更加容易和高效。
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