我正在 SQL Server 2008 中设计一个表,该表将存储用户列表和谷歌地图坐标(经度和纬度)。
我需要两个字段,还是可以用 1 个字段完成?
用于存储此类数据的最佳(或最常见)数据类型是什么?
公平警告!在接受使用 GEOGRAPHY 类型的建议之前,请确保您不打算使用 Linq 或实体框架来访问数据,因为它不受支持(截至 2010 年 11 月),您会很难过!
2017 年 7 月更新对于现在阅读此答案的人来说,它已经过时,因为它指的是过时的技术堆栈。有关更多详细信息,请参阅评论。
看看 SQL Server 2008 中引入的新空间数据类型。它们专为此类任务而设计,使索引和查询更加容易和高效。
更多信息:
MS TechNet:SQL Server 2008 空间数据类型,
MSDN:使用空间数据(数据库引擎)。
我不知道 SQL Server 的答案,但是......
在 MySQL 中将其保存为 FLOAT( 10, 6 )
这是来自 Google developer documentation 的官方建议。
CREATE TABLE `coords` (
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
lat
和 lng
优于 georgraphy
的实际情况。例如:find all point is with a rectangle。只是我不确定,我看到谷歌地图现在使用 7 位而不是 6 位数字?
我这样做的方式:我存储纬度和经度,然后我有第三列,它是第一列的自动派生地理类型。该表如下所示:
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)
。
我讨厌与那些说“这是一种新型,让我们使用它”的人相反。新的 SQL Server 2008 空间类型有一些优点 - 即效率,但您不能盲目地说总是使用该类型。这实际上取决于一些更大的问题。
例如,集成。这种类型在 .Net 中有一个等价的类型——但是互操作呢?支持或扩展旧版本的 .Net 怎么样?将这种跨服务层的类型暴露给其他平台怎么样?数据的规范化怎么样 - 也许您对 lat 或 long 作为独立的信息片段感兴趣。也许您已经编写了复杂的业务逻辑来处理 long/lat。
我并不是说你不应该使用空间类型——在很多情况下你应该。我只是说你应该在走这条路之前问一些更关键的问题。为了让我最准确地回答你的问题,我需要更多地了解你的具体情况。
单独存储 long/lat 或以空间类型存储都是可行的解决方案,根据您自己的情况,一种可能比另一种更可取。
您要做的是将纬度和经度存储为新的 SQL2008 空间类型 -> 地理。
这是一张桌子的屏幕截图,我有。
alt text http://img20.imageshack.us/img20/6839/zipcodetable.png
在此表中,我们有两个存储地理数据的字段。
边界:这是作为邮政编码边界的多边形
CentrePoint:这是表示该多边形视觉中点的纬度/经度点。
您想将其作为 GEOGRAPHY 类型保存到数据库的主要原因是,您可以利用它的所有 SPATIAL 方法 -> 例如。多边形中的点、两点之间的距离等。
顺便说一句,我们还使用 Google 的 Maps API 来检索经纬度数据并将其存储在我们的 Sql 2008 DB 中——所以这种方法确实有效。
SQL Server 支持空间相关信息。您可以在 http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx 中查看更多信息。
或者,您可以将信息存储为两个基本字段,通常浮点数是大多数设备报告的标准数据类型,并且在一英寸或两英寸内足够准确 - 对于谷歌地图来说已经足够了。
注意:这是基于最近的 SQL 服务器、.NET 堆栈更新的最新答案
谷歌地图中的纬度和经度应在地理数据类型下存储为 SQL 服务器中的点(注意大写 P)数据。
假设您当前的数据以 varchar 形式存储在表 Sample
中的列 lat
和 lon
下,以下查询将帮助您转换为地理
alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go
PS:下次当您使用地理数据在此表上进行选择时,除了“结果”和“消息”选项卡外,您还将获得如下所示的“空间结果”选项卡以进行可视化
https://i.stack.imgur.com/lsYVn.png
如果您使用的是 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);
}
}
https://stackoverflow.com/a/25563269/3850405
如果您只是要将它替换为一个 URL,我想一个字段会这样做 - 所以您可以形成一个类似的 URL
http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6
但由于它是两条数据,我会将它们存储在单独的字段中
将两者都存储为浮点数,并在它们上使用唯一的关键字.i.em
create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);
House A
,并将搬到 House B
,即 Alice 曾经居住的房子。很快 Bob 将无法保存他的地址(位置),因为 Alice 还没有更新她的地址(或者永远不会更新)。