SORU
13 EYLÜL 2011, Salı


Neden SQL Server 2008 coğrafya veri türü kullanılır?

Müşteri veritabanı ile birlikte standart Adres alanları (Cadde, Şehir, vb.) saklamak istiyorum bilgi yeni parçalardan biri yaratmayı ediyorum coğrafi konumu Adres. Tek kullanma durumu var aklında olduğu için izin kullanıcılar için harita koordinatları Google maps adresini olamaz aksi halde buldum ki bu çok sık olur alan yeni geliştirilen, ya da bir uzak/kırsal yer.

Benim ilk eğim ondalık değerleri enlem ve boylam saklamak için, ama sonra SQL Server 2008 R2 geography veri türüne sahip olduğunu hatırladım. Kesinlikle hiçbir deneyimi geography, kullanıyorum ve ilk araştırmam, benim senaryo için overkill gibi görünüyor.

Örneğin, enlem ve boylam decimal(7,4), ben de saklı ile çalışmak için bunu yapabilirsiniz:

insert into Geotest(Latitude, Longitude) values (47.6475, -122.1393)
select Latitude, Longitude from Geotest

ama geography ile bunu yapmak istiyorum:

insert into Geotest(Geolocation) values (geography::Point(47.6475, -122.1393, 4326))
select Geolocation.Lat, Geolocation.Long from Geotest

Bir iş de değilbuçok daha karmaşık, neden gerek yok diye karmaşıklığı Ekle?

Kullanma fikri ben terk etmeden önce geography, orada düşünmelisiniz bir şey var mı? Konumu Enlem ve Boylam alanlar indeksleme vs kayma dizin kullanmak için arama yapmak için daha hızlı olabilir mi? Farkında değilim geography kullanmanın yararları vardır? Ya da, öbür tarafta, orada geography kullanarak beni vazgeçirmek istiyorsunuz Bilmem Gereken uyarılar?


Güncelleme

@Erik Philips yapmak için yeteneği getirdi yakınlık çok cool geography ile arar.

Öte yandan, hızlı bir test enlem ve boylam select basit geography (detaylar aşağıda) kullanırken önemli ölçüde daha yavaş olduğunu gösteriyor. başka accepted answer yorum geography soru bana temkinli ve:

@Rica ederim SaphuA. Bir not bir kullanarak ÇOK dikkatli olarak null COĞRAFYA veri türü bir sütun üzerinde kayma dizin. Bazı vardır ciddi performans, böylece COĞRAFYA sütun null olmayan sorun olun eğer şema değiştirmek için varsa bile. – Tomas 11:18 de 18 Haz

Sonuçta, vs-kapalı ticaret performans ve karmaşıklığı yakınlık yapma olasılığı tartı arar, bu durumda geography kullanımı feragat etmeye karar verdim.


Koştum test ayrıntıları:

İki masa, bir geography kullanarak ve başka bir enlem için decimal(9,6) kullanma ve boylam yarattım:

CREATE TABLE [dbo].[GeographyTest]
(
    [RowId] [int] IDENTITY(1,1) NOT NULL,
    [Location] [geography] NOT NULL,
    CONSTRAINT [PK_GeographyTest] PRIMARY KEY CLUSTERED ( [RowId] ASC )
) 

CREATE TABLE [dbo].[LatLongTest]
(
    [RowId] [int] IDENTITY(1,1) NOT NULL,
    [Latitude] [decimal](9, 6) NULL,
    [Longitude] [decimal](9, 6) NULL,
    CONSTRAINT [PK_LatLongTest] PRIMARY KEY CLUSTERED ([RowId] ASC)
) 

ve tek bir satır, her bir tabloya aynı enlem ve boylam değerleri kullanarak eklenen:

insert into GeographyTest(Location) values (geography::Point(47.6475, -122.1393, 4326))
insert into LatLongTest(Latitude, Longitude) values (47.6475, -122.1393)

Son olarak, aşağıdaki kod çalışan, benim makinede, enlem ve boylam seçme geography kullanırken 5 kez daha yavaş, yaklaşık olarak gösterir.

declare @lat float, @long float,
        @d datetime2, @repCount int, @trialCount int, 
        @geographyDuration int, @latlongDuration int,
        @trials int = 3, @reps int = 100000

create table #results 
(
    GeographyDuration int,
    LatLongDuration int
)

set @trialCount = 0

while @trialCount < @trials
begin

    set @repCount = 0
    set @d = sysdatetime()

    while @repCount < @reps
    begin
        select @lat = Location.Lat,  @long = Location.Long from GeographyTest where RowId = 1
        set @repCount = @repCount   1
    end

    set @geographyDuration = datediff(ms, @d, sysdatetime())

    set @repCount = 0
    set @d = sysdatetime()

    while @repCount < @reps
    begin
        select @lat = Latitude,  @long = Longitude from LatLongTest where RowId = 1
        set @repCount = @repCount   1
    end

    set @latlongDuration = datediff(ms, @d, sysdatetime())

    insert into #results values(@geographyDuration, @latlongDuration)

    set @trialCount = @trialCount   1

end

select * 
from #results

select avg(GeographyDuration) as AvgGeographyDuration, avg(LatLongDuration) as AvgLatLongDuration
from #results

drop table #results

Sonuçlar:

GeographyDuration LatLongDuration
----------------- ---------------
5146              1020
5143              1016
5169              1030

AvgGeographyDuration AvgLatLongDuration
-------------------- ------------------
5152                 1022

Daha şaşırtıcı olansa, hiçbir satır seçili olduğunda bile, örneğin yerde yok RowId = 2,, geography seçme hala yavaş olduğunu

GeographyDuration LatLongDuration
----------------- ---------------
1607              948
1610              946
1607              947

AvgGeographyDuration AvgLatLongDuration
-------------------- ------------------
1608                 947

CEVAP
13 EYLÜL 2011, Salı


Eğer herhangi bir kayma hesaplama yapmayı planlıyorsanız, EF 5.0 gibi SERİ İfadeler sağlar:

private Facility GetNearestFacilityToJobsite(DbGeography jobsite)
{   
    var q1 = from f in context.Facilities            
             let distance = f.Geocode.Distance(jobsite)
             where distance < 500 * 1609.344     
             orderby distance 
             select f;   
    return q1.FirstOrDefault();
}

Sonra da Coğrafya kullanmak için çok iyi bir nedeni var.

Explanation of spatial within Entity Framework.

Creating High Performance Spatial Databases ile güncellendi

Noel Abrahams Answer üzerinde belirtildiği gibi:

Bir not alan, her koordinat saklı olarak bir çift duyarlıklı kayan noktalı sayı 64 bit (8 bayt) uzunluğunda ve 8-bayt ikili değer kabaca 15 basamak ondalık hassas, bu yüzden karşılaştırma ondalık(9,6) 5 bayt, değil mi tam olarak adil bir karşılaştırma. Ondalık gerçek bir karşılaştırma için her LatLong için Ondalık(15,12) (9 bayt) (toplam 18 bayt) en az olması gerekir.

Karşılaştırma depolama türleri:

CREATE TABLE dbo.Geo
(    
geo geography
)
GO

CREATE TABLE dbo.LatLng
(    
    lat decimal(15, 12),   
    lng decimal(15, 12)
)
GO

INSERT dbo.Geo
SELECT geography::Point(12.3456789012345, 12.3456789012345, 4326) 
UNION ALL
SELECT geography::Point(87.6543210987654, 87.6543210987654, 4326) 

GO 10000

INSERT dbo.LatLng
SELECT  12.3456789012345, 12.3456789012345 
UNION
SELECT 87.6543210987654, 87.6543210987654

GO 10000

EXEC sp_spaceused 'dbo.Geo'

EXEC sp_spaceused 'dbo.LatLng'

Sonuç:

name    rows    data     
Geo     20000   728 KB   
LatLon  20000   560 KB

Coğrafya veri türü 0 daha fazla yer kaplıyor.

Coğrafya veri türü yalnızca bir Nokta depolama için sınırlı değildir ayrıca LineString, CircularString, CompoundCurve, Polygon, CurvePolygon, GeometryCollection, MultiPoint, MultiLineString, and MultiPolygon and more saklayabilirsiniz. Herhangi bir girişim için mağaza bile en basit Coğrafya türleri (Lat/Uzun) ötesinde bir Noktası (örneğin LİNESTRİNG(1 1, 2 2) örnek) tabi ek satırlar için her nokta, bir sütun için sıralama düzeni her noktası ve başka bir sütun için bir gruplandırma satır. SQL Server da Area, Boundary, Length, Distances, and more hesaplama içeren Coğrafya veri türleri için yöntemleri vardır.

Akılsızca Sql Server Ondalık Enlem ve Boylam mağaza gibi görünüyor.

Güncelleme 2

Eğer mesafe gibi herhangi bir hesaplama yapmayı planlıyorsanız, alan, vb, düzgün toprak yüzeyi üzerinde bu hesaplamak zor. Her Coğrafya türü SQL Server saklı da Spatial Reference ID ile saklanır. Bu kimliğin farklı küreler (dünya 4326) olabilir. Bu SQL Server hesaplamaları aslında doğru yeryüzü (toprak yüzeyi ile olabilir as-the-crow-flies yerine) yüzeyi üzerinde hesaplar.

enter image description here

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jon Reed

    Jon Reed

    14 AĞUSTOS 2006
  • Michael Zhang

    Michael Zhan

    8 EYLÜL 2012
  • Samvith V Rao

    Samvith V Ra

    20 EKİM 2006