ฉันกำลังออกแบบตารางใน SQL Server 2008 ที่จะจัดเก็บรายชื่อผู้ใช้และ Google Maps Co-ordinate (ลองจิจูดและละติจูด)
ฉันต้องการสองช่องหรือสามารถทำได้ด้วย 1?
ชนิดข้อมูลที่ดีที่สุด (หรือที่พบบ่อยที่สุด) ที่จะใช้ในการจัดเก็บข้อมูลประเภทนี้คืออะไร
ฉันกำลังออกแบบตารางใน SQL Server 2008 ที่จะจัดเก็บรายชื่อผู้ใช้และ Google Maps Co-ordinate (ลองจิจูดและละติจูด)
ฉันต้องการสองช่องหรือสามารถทำได้ด้วย 1?
ชนิดข้อมูลที่ดีที่สุด (หรือที่พบบ่อยที่สุด) ที่จะใช้ในการจัดเก็บข้อมูลประเภทนี้คืออะไร
คำตอบ:
ดูประเภทข้อมูลเชิงพื้นที่ใหม่ที่เปิดตัวใน SQL Server 2008 ซึ่งได้รับการออกแบบมาสำหรับงานประเภทนี้และทำให้การจัดทำดัชนีและการสืบค้นง่ายขึ้นและมีประสิทธิภาพมากขึ้น
ข้อมูลมากกว่านี้:
MSDN: การทำงานกับข้อมูลเชิงพื้นที่ (โปรแกรมฐานข้อมูล)
คำเตือนที่เป็นธรรม! ก่อนที่จะรับคำแนะนำในการใช้ประเภท GEOGRAPHY ตรวจสอบให้แน่ใจว่าคุณไม่ได้วางแผนที่จะใช้ Linq หรือ Entity Framework เพื่อเข้าถึงข้อมูลเนื่องจากไม่ได้รับการสนับสนุน (ณ เดือนพฤศจิกายน 2010) และคุณจะต้องเสียใจ!
อัปเดตกรกฎาคม 2560
สำหรับผู้ที่อ่านคำตอบนี้ในตอนนี้ถือว่าล้าสมัยเนื่องจากอ้างถึงสแต็คเทคโนโลยีที่ล้าสมัย ดูความคิดเห็นสำหรับรายละเอียดเพิ่มเติม
ฉันไม่รู้คำตอบสำหรับ SQL Server แต่ ...
ในMySQLบันทึกเป็นไฟล์FLOAT( 10, 6 )
นี้เป็นคำแนะนำอย่างเป็นทางการจากเอกสารนักพัฒนา Google
CREATE TABLE `coords` (
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;
lat
และมีlng
ประสิทธิภาพสูงกว่าgeorgraphy
แม้จะมีดัชนีความหนาแน่นสูงใน SQL 2014 ก็ตามตัวอย่างเช่นค้นหาจุดทั้งหมดโดยใช้สี่เหลี่ยมผืนผ้า แต่ฉันไม่แน่ใจฉันเห็นว่าตอนนี้ Google Maps ใช้ 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 - แล้ว interop ล่ะ? แล้วการสนับสนุนหรือขยาย. Net เวอร์ชันเก่าล่ะ? แล้วการเปิดเผยประเภทนี้ในชั้นบริการไปยังแพลตฟอร์มอื่น ๆ ล่ะ สิ่งที่เกี่ยวกับการทำให้ข้อมูลเป็นมาตรฐาน - บางทีคุณอาจสนใจ lat หรือ long เป็นข้อมูลเดี่ยว ๆ บางทีคุณได้เขียนตรรกะทางธุรกิจที่ซับซ้อนเพื่อจัดการ long / lat แล้ว
ฉันไม่ได้บอกว่าคุณไม่ควรใช้ประเภทเชิงพื้นที่ - ในหลาย ๆ กรณีคุณควร ฉันแค่บอกว่าคุณควรถามคำถามที่สำคัญกว่านี้ก่อนที่จะไปตามเส้นทางนั้น เพื่อให้ฉันตอบคำถามของคุณได้ถูกต้องที่สุดฉันต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับสถานการณ์เฉพาะของคุณ
การจัดเก็บ long / lat แยกกันหรือในประเภทเชิงพื้นที่เป็นทั้งโซลูชันที่ทำงานได้และวิธีหนึ่งอาจดีกว่าสำหรับอีกแบบขึ้นอยู่กับสถานการณ์ของคุณเอง
สิ่งที่คุณต้องการทำคือจัดเก็บละติจูดและลองจิจูดเป็น SQL2008 Spatial type ใหม่ -> GEOGRAPHY
นี่คือภาพหน้าจอของตารางที่ฉันมี
ข้อความแสดงแทน http://img20.imageshack.us/img20/6839/zipcodetable.png
ในตารางนี้เรามีสองฟิลด์ที่เก็บข้อมูลภูมิศาสตร์
สาเหตุหลักที่คุณต้องการบันทึกลงในฐานข้อมูลเป็นประเภท GEOGRAPHY คือเพื่อให้คุณสามารถใช้ประโยชน์จากวิธีการพิเศษทั้งหมดได้ -> เช่น ชี้ในโพลีระยะห่างระหว่างจุดสองจุด ฯลฯ
BTW เรายังใช้ Maps API ของ Google เพื่อดึงข้อมูล lat / long และจัดเก็บไว้ใน Sql 2008 DB ของเราดังนั้นวิธีนี้จึงใช้ได้ผล
SQL Server รองรับข้อมูลที่เกี่ยวข้องกับเชิงพื้นที่ คุณสามารถดูข้อมูลเพิ่มเติมได้ที่http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx
อีกทางเลือกหนึ่งคุณสามารถจัดเก็บข้อมูลเป็นฟิลด์พื้นฐานสองช่องโดยปกติแล้ว float เป็นประเภทข้อมูลมาตรฐานที่รายงานโดยอุปกรณ์ส่วนใหญ่และมีความแม่นยำเพียงพอสำหรับภายในหนึ่งหรือสองนิ้วซึ่งมากกว่าที่เพียงพอสำหรับ Google Maps
หมายเหตุ : นี่เป็นคำตอบล่าสุดที่อ้างอิงจากเซิร์ฟเวอร์ SQL ล่าสุดการอัปเดตสแต็ก. NET
ละติจูดและลองจิจูดจาก Google Maps ควรจัดเก็บเป็นข้อมูล Point (note capital P) ในเซิร์ฟเวอร์ SQL ภายใต้ประเภทข้อมูลภูมิศาสตร์
สมมติว่าข้อมูลปัจจุบันของคุณถูกจัดเก็บในตารางSample
เป็น varchar ใต้คอลัมน์lat
และlon
แบบสอบถามด้านล่างจะช่วยให้คุณแปลงเป็นภูมิศาสตร์ได้
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);
}
}
หากคุณกำลังจะแทนที่เป็น 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
อยู่บ้านที่อลิซเคยอาศัยอยู่ อีกไม่นานบ็อบจะไม่สามารถบันทึกที่อยู่ (สถานที่) ของเขาได้เนื่องจากอลิซยังไม่ได้อัปเดตข้อมูลของเธอหรือจะไม่ทำเลย