sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man förstår SQL Server Geografi Data Type

Datatypen SQL Server Geografi skiljer sig från andra typer helt enkelt för att du inte använder den ofta. Det är inte som varchar , int , flyta eller DateTime finns i varje tabell, åtminstone i en typ.

Behöver vi datatypen SQL Server Geography? För att förstå något nytt måste vi svara på tre grundläggande frågor:

Vilka problem löser det ? Svaret ligger i användningsfall.
Vad ingår i att studera det? Du kommer att lära dig några grundläggande definitioner och akronymer. Jag samlade bara på det viktiga, så det kommer inte att tråka ut dig.
Finns det exempel för att ytterligare förklara hur det fungerar och är det lätt att implementera? Vår sort lever med kod. Vi äter och sover med den. Så vi kommer att ha exempelkoder i det här inlägget.

Det är inte ett inlägg för att fylla på dig med teknisk jargong och syntax som det är. Du är bra att gå när du har knäckt grunderna i SQL Server geografidatatyp. Låter det bra?

Låt oss dyka in.

Använd fall av rumslig data

Låt oss börja med det mest uppenbara och översta – den allmänna termen "rumsliga data."

Rumslig eller geospatial data är data om objekt, händelser eller fenomen som finns på jordens yta. Det är med andra ord information stoppad på en karta. Tänk på Google Maps eller Waze, till exempel.

Men det finns mer:

  • Leta reda på ett företags lastbil via en webbplats eller mobilapp.
  • Hitta intressanta platser som närliggande restauranger, banker eller sjukhus.
  • Analysera data om jordbävning, spridning av covid-19, översvämningar eller vägtrafik – geospatial analys.

Och så vidare.

Flera databasplattformar har att göra med rumslig data, men vi kommer att fokusera på bara en.

Vad är SQL Server Geography Data Type?

Microsoft lade till datatyper för geografi och geometri i SQL Server 2008. Geografi representerar data i ett koordinatsystem runt jorden. Den är också implementerad som en .Net CLR-datatyp, som har egenskaper som latitud eller longitud.

Det här inlägget fokuserar på geografidatatyp och dess tillämpningar, särskilt inom:

  • Intressepunkter, som att hitta närliggande restauranger och en exempelfråga.
  • Geospatial analys.

Eftersom detta är en datatyp skapar vi en tabell. Sedan definierar vi en kolumn eller kolumner som geografi. Och slutligen gör vi ett rumsligt index på dessa kolumner.

När du frågar efter en tabell med en geografikolumn blir utdata binär.

Låt oss försöka köra ett elementärt exempel nedan:

SELECT 
 [CityID]
,[CityName]
,[GeoLocation]
FROM [Cities]

Figur 1 nedan visar resultatuppsättningen:

När en resultatuppsättning innehåller rumslig data visas ett rumsliga resultat fliken kommer också att visas. Figur 2 illustrerar de rumsliga resultaten från frågan ovan:

Nu, vad har just hänt?

Det verkar som att det är långt ifrån enkelt och användbart att titta på resultatuppsättningen, än mindre prickarna längs rutnätslinjerna. Jag visade dig vad du kan förvänta dig vid den allra första SELECT uttalande om geografidatatyper. Nästa avsnitt kommer att utveckla ett mycket bättre perspektiv.

Skapa SQL Server Geografi-instanser

Du behöver en instans för att arbeta på data med SQL Server geografidatatypen. Det finns fyra sätt att göra en geografiinstans:

  1. från en annan geografiinstans
  2. med en välkänd text (WKT)
  3. med en välkänd binär (WKB)
  4. från en Geography Markup Language (GML) textinmatning

Låt oss fokusera på att använda en välkänd text.

Använda välkänd text (WKT)

Denna representation grundar sig på Open Geospatial Consortium (OGC). Det tillåter utbyte av geografidata i textform.

Ta vårt tidigare exempel, men istället för en binär utdata kommer vi att konvertera den till en sträng:

SELECT 
 [CityID]
,[CityName]
,[GeoLocation].ToString() AS GeoLocationString
FROM [Cities]

Lägg märke till ToString () metod. Det kommer att konvertera utdata till strängvärdet. Du kan se resultatet i figur 3 nedan:

Bättre? Tja, det är fortfarande bara siffror. Men vad händer om jag säger att dessa siffror är latitud och longitud för de städerna? Det är mer vettigt, eller hur?

Det är en välkänd text (WKT), och den är väsentlig när du lägger in data i kolumnen. Mer om det senare. Nu behöver vi en sak till att undersöka.

Spatial Reference Identifier (SRID)

Förutom en välkänd text har varje geografiinstans en Spatial Reference Identifier (SRID). Det är nödvändigt för att mäta geografiförekomster (platser eller punkter) i en kartläggning av rund jord.

Den mest utbredda måttenheten är i meter eller kvadratmeter, betecknad med SRID 4326. Alla andra SRID:n finns i sys.spatial_reference_systems .

Dina geografikolumner kan ha olika SRID. Observera att när du utför operationer på två geografiska instanser, som att mäta deras avstånd. Båda instanserna bör ha samma SRID, annars returnerar det digNULL .

STGeomFromText

Efter att ha lärt sig om WKT och SRID kräver att skapa en geografiinstans en metod som heter STGeomFromText . Den har följande syntax:

geografi::STGeomFromText( , SRID )

Exempel:

INSERT INTO Cities
(CityName, GeoLocation)
VALUES
('CITY OF MANILA',geography::STGeomFromText('POINT(14.6077 120.98202)', 4326))

Låt oss kolla in parametervärdena:

‘POINT(14.6077 120.98202)’ – en välkänd text av en punkt på kartan med latitud 14,6077 och longitud 120,98202. Detta motsvarar Manila, Filippinernas huvudstad.

4326 – den rumsliga referensidentifieraren

Låt oss gå direkt in i exempel och använda denna nya pärla vi hittade.

SQL Server Geografi Datatyp Praktiska exempel

Vi kommer att ha två vanliga applikationer för att få dig igång med geografidata.

Beräkna avstånd (närmaste granne)

En vanlig applikation i geografi rumslig data kallas för den närmaste grannfrågan. I den här frågan vill du veta hur långt eller nära något är till ett annat objekt eller en annan plats.

I mitt inlägg om SQL-grafen beskrev jag hur en kund kunde hitta de närliggande restaurangerna från den aktuella platsen. Låt oss hänvisa till det exemplet igen:

-- Query the location of the customer
DECLARE @deliveryLocation GEOGRAPHY

SELECT @deliveryLocation = Locations.GeoLocation
FROM Customers, willReceiveIn, Locations
WHERE MATCH(Customers-(willReceiveIn)->Locations)
AND Customers.CustomerID = 3

-- Query the restaurants within 1000 meters from the location of the customer
SELECT
 Restaurants.Name
,Restaurants.Description
,Restaurants.Opening
,Restaurants.Closing
,Locations.Description
,ROUND(Locations.GeoLocation.STDistance(@deliveryLocation),2) AS Distance
FROM Restaurants, isLocated, Locations
WHERE MATCH(Restaurants-(isLocated)->Locations)
AND locations.GeoLocation.STDistance(@deliveryLocation) <= 1000
ORDER BY Distance

Hemligheten bakom denna fråga om närmaste granne är STDistance (). Den behöver två geografiska platser:en för kunden och en annan för restaurangerna inom 1000 meter från kundens plats.

Det coola är att samma koncept gäller för andra idéer som involverar två eller flera platser.

Geospatial analys med Power BI

En annan tillämpning av rumslig data använder den för geospatial analys. I det här avsnittet har vi ett exempel som använder COVID-19-fall per plats och presenterar det med Power BI.

(Till exempel, här är mer information om vad som är Power BI och hur man installerar det)

Det är gratis att installera Power BI Desktop. En av standardvisualiseringarna är kartvisualiseringen med Bing Maps. Vi behöver inte koordinater för kända platser som länder och amerikanska delstater. Se detta i exemplet nedan:

Notera den röda rutan i figur 4. Latitud och longitud lämnas tomma, men bubblorna plottas på kartan helt okej.

Men i nästa exempel kommer vi att använda regioner och städer i Filippinerna. Koordinater är ett måste för att rita bubblorna korrekt.

VAD DU BEHÖVER

Innan vi går in på den köttiga delen av rapporten, här är de grundläggande sakerna vi behöver:

  • Power BI Desktop
  • Kartvisualisering
  • Tabell och frågor
  • Exempeldata

FÖRBEREDA DATA

Förbereda tabellerna och vyerna

I början måste vi ställa in behållarna för vår data. Så vi kräver följande tabeller:

  1. Städer – en lista över städer i Filippinerna kategoriserade efter region.
  2. Regioner – en lista över områden i Filippinerna
  3. CityCases – en lista som innehåller antalet ärenden för varje stad.

Nedan är tabellstrukturen:

CREATE TABLE [dbo].[Cities](
[CityID] [int] IDENTITY(1,1) NOT NULL,
[CityName] [varchar](50) NOT NULL,
[RegionID] [int] NOT NULL,
[GeoLocation] [geography] NULL,
 CONSTRAINT [PK_Cities] PRIMARY KEY CLUSTERED
(
[CityID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

CREATE TABLE [dbo].[Regions](
[RegionID] [int] IDENTITY(1,1) NOT NULL,
[Region] [varchar](50) NOT NULL,
[GeoLocation] [geography] NULL,
 CONSTRAINT [PK_Regions] PRIMARY KEY CLUSTERED
(
[RegionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

CREATE TABLE [dbo].[CityCases](
[CityCaseID] [int] IDENTITY(1,1) NOT NULL,
[CityID] [int] NOT NULL,
[DateReported] [date] NOT NULL,
[TotalCases] [int] NOT NULL,
[TotalDeaths] [int] NOT NULL,
 CONSTRAINT [PK_CityCases] PRIMARY KEY CLUSTERED
(
[CityCaseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[CityCases]  WITH CHECK ADD  CONSTRAINT [FK_CityCases_Cities] FOREIGN KEY([CityID])
REFERENCES [dbo].[Cities] ([CityID])
GO
ALTER TABLE [dbo].[CityCases] CHECK CONSTRAINT [FK_CityCases_Cities]
GO

Eftersom geografidatatypen är okänd för Power BI Map-visualisering måste du skapa vyer. Syftet är att exponera latitud och longitud från dessa kolumner. Vi gör detta för städerna och regionerna – se nedan:

CREATE VIEW vwCityCoordinates
AS
SELECT
 CityID
,CityName
,GeoLocation.Lat AS Latitude
,Geolocation.Long AS Longitude
,RegionID
FROM Cities

CREATE VIEW vwRegionCoordinates
AS
SELECT
 RegionID
,Region
,GeoLocation.Lat AS Latitude
,GeoLocation.Long AS Longitude
FROM Regions

Det är allt. lat och Lång är egenskaper för latitud och longitud. Det är nu möjligt att använda dem i vår Power BI-rapport.

Bygga upp data

Därefter måste du bygga upp data för våra tre tabeller.

Stort tack till Filippinernas hälsodepartement för att ha gjort datauppsättningen tillgänglig för allmänheten. Filen är i CSV-format. Filnamnkonventionen är DOH COVID Data Drop_ yyyymmdd – 04 Case Information.CSV.

Så här får du filen så att den blir bättre praktisk med vårt exempel:

  1. Klicka på länken till datamängden.
  2. Välj en månadsmapp. Augusti 2020 är i DOH COVID Data (08).
  3. Välj ett datum. Den 12 augusti 2020 är till exempel i DOH COVID Data Drop_20200812.
  4. Ladda ned DOH COVID Data Drop_ 20200812 – 04 Case Information.CSV. Upprepa steg 2-4 för att få rapporten för de andra dagarna.

Dessutom måste du importera dessa data till SQL Server. Så här gör du:

  1. Öppna CSV-filen i Excel.
  2. Lägg till en kolumn Datumrapporterad och fyll i alla poster med motsvarande datum. I det här fallet, 08/10/2020.
  3. Spara den som en Excel-fil (.xlsx).
  4. Exportera Excel-filen till SQL Server till en tabell som heter covid_ph .

Nu när data är klara i SQL Server är nästa uppgift att köra följande i SSMS-frågeredigeraren:

INSERT INTO CityCases
(CityID, DateReported, TotalCases, TotalDeaths)
SELECT DISTINCT
 c.CityID
,cp.DateReported
,(SELECT COUNT(*) FROM covid_ph cp1 WHERE cp1.CityMunRes = cp.CityMunRes AND                 
                               cp1.DateReported = cp.DateReported) AS TotalCases
,(SELECT COUNT(*) FROM covid_ph cp1 WHERE cp1.CityMunRes = cp.CityMunRes AND 
                               cp1.DateReported = cp.DateReported AND 
                               cp1.RemovalType='DIED') AS TotalDeaths
FROM covid_ph cp
INNER JOIN Cities c ON cp.CityMunRes = c.CityName
ORDER BY cp.DateReported

Under tiden finns det inga koordinater i datamängden vi använde. Så jag har manuellt lagt till latitud och longitud för regioner och städer från latlongdata.com.

Här är informationen för Regioner :

INSERT INTO Regions
(Region, GeoLocation)
VALUES
('BARMM',geography::STGeomFromText('POINT(121.987 6.42964)', 4326)),
('CAR',geography::STGeomFromText('POINT(121.466 17.4737)', 4326)),
('CARAGA',geography::STGeomFromText('POINT(125.492 9.78604)', 4326)),
('NCR',geography::STGeomFromText('POINT(120.984 14.5995)', 4326)),
('Region I: Ilocos Region',geography::STGeomFromText('POINT(120.381 17.5553)', 4326)),
('Region II: Cagayan Valley',geography::STGeomFromText('POINT(121.811 16.9754)', 4326)),
('Region III: Central Luzon',geography::STGeomFromText('POINT(120.712 15.4828)', 4326)),
('Region IV-A: CALABARZON',geography::STGeomFromText('POINT(121.079 14.1008)', 4326)),
('Region IV-B: MIMAROPA',geography::STGeomFromText('POINT(118.736 9.84321)', 4326)),
('Region IX: Zamboanga Peninsula',geography::STGeomFromText('POINT(123.259 8.15408)', 4326)),
('Region V: Bicol Region',geography::STGeomFromText('POINT(123.414 13.421)', 4326)),
('Region VI: Western Visayas',geography::STGeomFromText('POINT(122.537 11.005)', 4326)),
('Region VII: Central Visayas',geography::STGeomFromText('POINT(124.064 9.81687)', 4326)),
('Region VIII: Eastern Visayas',geography::STGeomFromText('POINT(125.039 12.2446)', 4326)),
('Region X: Northern Mindanao',geography::STGeomFromText('POINT(124.686 8.02016)', 4326)),
('Region XI: Davao Region',geography::STGeomFromText('POINT(126.089 7.30416)', 4326)),
('Region XII: SOCCSKSARGEN',geography::STGeomFromText('POINT(124.686 6.27069)', 4326))

Här är data från en ofullständig lista över städer för Städer tabell:

INSERT INTO Cities
(CityName, RegionID, GeoLocation)
VALUES
('CALOOCAN CITY',4,geography::STGeomFromText('POINT(120.967 14.6488)', 4326)),
('CITY OF LAS PIÑAS',4,geography::STGeomFromText('POINT(120.999 14.4325)', 4326)),
('CITY OF MAKATI',4,geography::STGeomFromText('POINT(121.033 14.5502)', 4326)),
('CITY OF MALABON',4,geography::STGeomFromText('POINT(120.957 14.6633)', 4326)),
('CITY OF MANDALUYONG',4,geography::STGeomFromText('POINT(121.039 14.5771)', 4326)),
('CITY OF MANILA',4,geography::STGeomFromText('POINT(120.982 14.6077)', 4326)),
('CITY OF MARIKINA',4,geography::STGeomFromText('POINT(121.097 14.6409)', 4326)),
('CITY OF MUNTINLUPA',4,geography::STGeomFromText('POINT(121.05 14.4209)', 4326)),
('CITY OF NAVOTAS',4,geography::STGeomFromText('POINT(120.933 14.6775)', 4326)),
('CITY OF PARAÑAQUE',4,geography::STGeomFromText('POINT(121.017 14.4664)', 4326)),
('CITY OF PASIG',4,geography::STGeomFromText('POINT(121.061 14.5876)', 4326)),
('CITY OF SAN JUAN',4,geography::STGeomFromText('POINT(121.037 14.6001)', 4326)),
('CITY OF VALENZUELA',4,geography::STGeomFromText('POINT(120.967 14.6823)', 4326)),
('PASAY CITY',4,geography::STGeomFromText('POINT(121 14.5505)', 4326)),
('PATEROS',4,geography::STGeomFromText('POINT(121.071 14.5487)', 4326)),
('QUEZON CITY',4,geography::STGeomFromText('POINT(121.033 14.633)', 4326)),
('TAGUIG CITY',4,geography::STGeomFromText('POINT(121.062 14.5216)', 4326)),
('ALFONSO',8,geography::STGeomFromText('POINT(120.861 14.1214)', 4326)),
('AMADEO',8,geography::STGeomFromText('POINT(120.922 14.1693)', 4326)),
('BACOOR CITY',8,geography::STGeomFromText('POINT(120.974 14.413)', 4326)),
('CARMONA',8,geography::STGeomFromText('POINT(121.041 14.3108)', 4326)),
('CAVITE CITY',8,geography::STGeomFromText('POINT(120.897 14.4791)', 4326)),
('CITY OF DASMARIÑAS',8,geography::STGeomFromText('POINT(120.959 14.299)', 4326)),
('CITY OF GENERAL TRIAS',8,geography::STGeomFromText('POINT(120.907 14.3214)', 4326)),
('GEN. MARIANO ALVAREZ',8,geography::STGeomFromText('POINT(121.013 14.3051)', 4326)),
('GENERAL EMILIO AGUINALDO',8,geography::STGeomFromText('POINT(120.792 14.1931)', 4326)),
('IMUS CITY',8,geography::STGeomFromText('POINT(120.941 14.4064)', 4326)),
('INDANG',8,geography::STGeomFromText('POINT(120.873 14.192)', 4326)),
('KAWIT',8,geography::STGeomFromText('POINT(120.904 14.441)', 4326)),
('MAGALLANES',8,geography::STGeomFromText('POINT(120.746 14.1583)', 4326)),
('MARAGONDON',8,geography::STGeomFromText('POINT(120.735 14.253)', 4326)),
('MENDEZ (MENDEZ-NUÑEZ)',8,geography::STGeomFromText('POINT(120.902 14.1312)', 4326)),
('NAIC',8,geography::STGeomFromText('POINT(120.792 14.2965)', 4326)),
('NOVELETA',8,geography::STGeomFromText('POINT(120.88 14.4279)', 4326)),
('ROSARIO',8,geography::STGeomFromText('POINT(120.857 14.414)', 4326)),
('SILANG',8,geography::STGeomFromText('POINT(120.969 14.2142)', 4326)),
('TAGAYTAY CITY',8,geography::STGeomFromText('POINT(120.962 14.1153)', 4326)),
('TANZA',8,geography::STGeomFromText('POINT(120.85 14.3429)', 4326)),
('TERNATE',8,geography::STGeomFromText('POINT(120.678 14.2714)', 4326)),
('TRECE MARTIRES CITY (CAPITAL)',8,geography::STGeomFromText('POINT(120.868 14.2822)', 4326))

Nu när uppgifterna är klara är vi redo att förbereda rapporten.

FÖRBAR RAPPORTEN

Innan vi börjar behöver vi två sidor med rapporter. En sida är för data per region och den andra sidan är per stad.

COVID-19-rapport per region

Här är enkla steg för att skapa rapporten per region:

  1. Anslut till SQL Server från Power BI. Ange servern och databasen.
  2. Välj de tabeller och vyer du behöver för rapporten.

3. Definiera sambanden – se figur 6 nedan. För mer information om hur du definierar relationer i Power BI, besök den här sidan.

4. Klicka på kartvisualiseringen och fyll i egenskaperna. Bind latitud- och longitudegenskaperna från vwRegionCoordinates . Sedan verktygstipset från vwRegionCoordinates Region kolumn. Och slutligen, storleken från CityCases ' TotalCases kolumn. Se figur 7 nedan:

  1. Lägg till en Slicer och bind den till DateReported från CityCases tabell.
  2. Sätt i ett kort och bind det till TotalCases från CityCases tabell
  3. Lägg till ett klustrad stapeldiagram. Bind egenskapen Axis till Region kolumn från vwRegionCoordinates . Bind sedan värdena till TotalCases kolumn från CityCases . Se figur 8 nedan:

Efter stegen ovan ser du det slutliga utseendet. Det bör likna figur 9 nedan:

COVID-19-rapport per stad

Första sidan är klar. Det borde inte vara svårt att lägga till nästa sida för rapporten per stad.

Här är stegen:

  1. Lägg till en ny sida genom att klicka på + i den nedre delen av fönstret och byt namn på den per stad (Filippinerna).
  2. Inkludera en slicer och bind den till regionen från vwRegionCoordinates .
  3. Sätt i en annan slicer och bind den till DateReported från CityCases .
  4. Lägg till ett kort och bind det till TotalCases från CityCases .
  5. Infoga en kartvisualisering. Du definierar egenskaperna för latitud och longitud från vwCityCoordinates . Verktygstipset är från vwCityCoordinates Stadsnamn kolumn, och storleken är från CityCases ' TotalCases kolumn.
  6. Lägg till ett klustrat stapeldiagram och bind axeln till Stadsnamn kolumn från vwCityCoordinates och värden till TotalCases från CityCases .

Det slutliga utseendet på rapporten per stad bör likna figur 10 nedan:

Vad är grejen med att använda kartor för analys jämfört med att titta på stapel- eller linjediagram?

Först och främst är det inte bara för estetik och för att imponera på din publik med iögonfallande rapporter. Ännu viktigare, det ger dem en tydligare förståelse av data i förhållande till en plats.

I vårt exempel kan du se var pandemiproblemet är mer utbrett baserat på hur stora bubblorna är. Dessutom kan vi se och jämföra med ett ögonkast antalet fall på olika platser i förhållande till varandra. Detta kommer också att hjälpa regeringstjänstemän att fatta bättre beslut.

Vårt rapportexempel är för enkelt, men det visar hur SQL Server geografidatatyper kan hjälpa dig med geospatial analys.

Slutsats

Har du förstått vad som finns i det för dig när du använder geografiska geografiska datatyper?

  • Spatial eller geospatial data står för data om punkter som finns på jordens yta.
  • Den kan användas för "närmaste granne"-frågan som söker efter närliggande biografer, restauranger, klubbar, etc.
  • Det är också praktiskt för geospatial dataanalys, som rapporten vi skapade i Power BI.
  • De grundläggande elementen i att skapa en geografiinstans är saker som välkänd text (WKT), spatial reference identifier (SRID) och metoden STGeomFromText .

I det här inlägget berörde vi bara en del av vad rumslig data i SQL Server kan göra för dig. Du kanske inte använder dem alla på en gång, men de vanligaste användningsfallen är här för att komma igång. Varför inte utforska mer från referenserna från Microsoft nedan?

  • Översikt över rumslig data
  • Spatiala datatyper
  • Indexering av rumslig data

Om du gillar det här inlägget, vänligen dela det med dina favoritplattformar för sociala medier.


  1. Hur man skapar flera en till en

  2. PostgreSQL 11:Vad är nytt

  3. Avancerad SQL:Infoga utdata från den parameteriserade tabellvärderade funktionen i SQL-tabellen

  4. SQL Server UNION - Vilket är standardbeteendet ORDER BY Behavior