我正在设计一个 SQL Server 2008 中的表,用于存储用户列表和 Google 地图坐标(经度和纬度)。
我需要两个字段,还是只需要一个字段就可以了?
什么是存储这种数据的最佳(或最常见)数据类型?
我正在设计一个 SQL Server 2008 中的表,用于存储用户列表和 Google 地图坐标(经度和纬度)。
我需要两个字段,还是只需要一个字段就可以了?
什么是存储这种数据的最佳(或最常见)数据类型?
提醒!在采用GEOGRAPHY类型之前,请确保您不打算使用Linq或Entity Framework来访问数据,因为它们不受支持(截至2010年11月),否则你会感到难过!
更新于2017年7月
对于现在阅读本答案的人来说,它已经过时了,因为它是针对过时的技术堆栈。请参见评论获取更多详细信息。
看一下在SQL Server 2008中引入的新空间数据类型。这些类型是为这种任务而设计的,使索引和查询变得更加容易和高效。
更多信息:
我不知道SQL Server的答案,但是...
在MySQL中,将其保存为FLOAT( 10, 6 )
这是来自Google开发者文档的官方建议。
CREATE TABLE `coords` (
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
我的做法是:我存储了纬度和经度,然后我有第三列是根据前两列自动派生的地理类型。表格如下:
CREATE TABLE [dbo].[Geopoint]
(
[GeopointId] BIGINT NOT NULL PRIMARY KEY IDENTITY,
[Latitude] float NOT NULL,
[Longitude] float NOT NULL,
[ts] ROWVERSION NOT NULL,
[GeographyPoint] AS ([geography]::STGeomFromText(((('POINT('+CONVERT([varchar](20),[Longitude]))+' ')+CONVERT([varchar](20),[Latitude]))+')',(4326)))
)
这使你可以在geoPoint列上进行空间查询,你也可以按需检索纬度和经度值以便于展示或提取为csv文件。
Point
比STGeomFromText
更好。例如:[geography]::Point([Latitude], [Longitude], 4326)
。 - default.kramer对于那些说“这里有一个新类型,让我们使用它”的人,我不想成为持反对意见的人。新的SQL Server 2008空间类型有一些优点-即效率,但你不能盲目地说总是使用该类型。这实际上取决于一些更大的问题。
举个例子,集成。这种类型在.Net中有一个等效类型-但是interop呢?如何支持或扩展旧版本的.Net?如何将此类型暴露到其他平台的服务层?数据规范化怎么办-也许您只对lat或long作为独立信息感兴趣。也许您已经编写了处理长/宽的复杂业务逻辑。
我并不是说您不应该使用空间类型-在许多情况下,您应该使用。我只是说,在走这条道路之前,您应该询问一些更加关键的问题。要最准确地回答您的问题,我需要了解您特定情况的更多信息。
将long/lat分别存储或以空间类型存储均是可行的解决方案,根据您自己的情况,其中一种可能更可取。
您需要做的是将纬度和经度存储为新的SQL2008空间类型-> GEOGRAPHY。
这是我拥有的一个表的截图。
alt text http://img20.imageshack.us/img20/6839/zipcodetable.png
在这个表中,我们有两个字段存储地理数据:
您希望将其保存到数据库中作为GEOGRAPHY类型的主要原因是,您可以利用所有SPATIAL方法->例如,点在Poly中,两点之间的距离等。
顺便说一下,我们还使用Google Maps API检索经纬度数据并将其存储在我们的Sql 2008 DB中--所以此方法确实有效。
SQL Server 支持与空间相关的信息。您可以在此处了解更多信息。
或者你可以将信息存储为两个基本字段,通常使用浮点数作为标准数据类型,大多数设备也会报告此类型,并且精度足以到达英寸或两英寸之内,对于Google Maps来说完全足够。
注意:这是基于最近SQL Server和.NET技术栈更新的答案
从Google Maps获取的纬度和经度应该作为Point(注意大写P)数据存储在SQL Server的地理数据类型中。
假设您当前的数据以Sample
表的lat
和lon
列形式存储为varchar,以下查询将帮助您转换为地理信息。
alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go
PS:下一次当您对这个带有地理数据的表进行选择时,除了结果和消息选项卡之外,您还将获得如下所示的空间结果选项卡,以便进行可视化。
如果您正在使用 Entity Framework 5 <,您可以使用 DbGeography
。以下是 MSDN 上的示例:
public class University
{
public int UniversityID { get; set; }
public string Name { get; set; }
public DbGeography Location { get; set; }
}
public partial class UniversityContext : DbContext
{
public DbSet<University> Universities { get; set; }
}
using (var context = new UniversityContext ())
{
context.Universities.Add(new University()
{
Name = "Graphic Design Institute",
Location = DbGeography.FromText("POINT(-122.336106 47.605049)"),
});
context. Universities.Add(new University()
{
Name = "School of Fine Art",
Location = DbGeography.FromText("POINT(-122.335197 47.646711)"),
});
context.SaveChanges();
var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)");
var university = (from u in context.Universities
orderby u.Location.Distance(myLocation)
select u).FirstOrDefault();
Console.WriteLine(
"The closest University to you is: {0}.",
university.Name);
}
https://msdn.microsoft.com/en-us/library/hh859721(v=vs.113).aspx
我在开始使用DbGeography
时遇到的问题之一是coordinateSystemId
。请参见下面的答案,其中包含了对此代码的出色解释和来源。public class GeoHelper
{
public const int SridGoogleMaps = 4326;
public const int SridCustomMap = 3857;
public static DbGeography FromLatLng(double lat, double lng)
{
return DbGeography.PointFromText(
"POINT("
+ lng.ToString() + " "
+ lat.ToString() + ")",
SridGoogleMaps);
}
}
http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6
但由于这是两个数据,我会将它们存储在不同的字段中。