webentwicklung-frage-antwort-db.com.de

Welcher Datentyp soll zum Speichern von Breiten- und Längengraddaten in SQL-Datenbanken verwendet werden?

Welcher Datentyp ist am besten geeignet, wenn Breiten- oder Längengraddaten in einer ANSI SQL-kompatiblen Datenbank gespeichert werden? Soll float verwendet werden oder decimal oder ...?

Ich bin mir bewusst, dass Oracle, MySQL und SQL Server einige spezielle Datentypen speziell für den Umgang mit Geodaten hinzugefügt haben, aber ich bin daran interessiert, wie Sie die Informationen in einer einfachen Vanilla-SQL-Datenbank speichern würden.

288
dthrasher

Decimal(9,6)

Wenn Sie nicht an die Genauigkeit und Skalierung von Parametern gewöhnt sind, finden Sie hier eine visuelle Formatzeichenfolge:

###.######

412
dotjoe

Wir verwenden float, aber jeder numerische Flavor mit 6 Dezimalstellen sollte auch funktionieren.

5
Keith

Nun, Sie haben gefragt, wie Breitengrad/Längengrad gespeichert werden soll, und meine Antwort lautet: Nein, Sie könnten erwägen, das WGS 84 (in Europa ETRS 89 ) zu verwenden, da es das ist Standard für Geo-Referenzen.

Abgesehen von diesen Details habe ich in den Tagen vor der endgültigen Unterstützung von SQL 2008 einen benutzerdefinierten Typ verwendet.

3
Kasper

Sie können ganz einfach eine Lat/Lon-Dezimalzahl in einem vorzeichenlosen Ganzzahlfeld speichern, anstatt sie in einen Ganzzahl- und einen Dezimalteil aufzuteilen und diese getrennt zu speichern.

als gespeicherte MySQL-Funktion:

CREATE DEFINER=`r`@`l` FUNCTION `PositionSmallToFloat`(s INT) 
RETURNS decimal(10,7)
DETERMINISTIC
RETURN if( ((s > 0) && (s >> 31)) , (-(0x7FFFFFFF - 
(s & 0x7FFFFFFF))) / 600000, s / 600000)

und zurück

CREATE DEFINER=`r`@`l` FUNCTION `PositionFloatToSmall`(s DECIMAL(10,7)) 
RETURNS int(10)
DETERMINISTIC
RETURN s * 600000

Das muss in einem nsigned int (10) gespeichert werden, das funktioniert sowohl in mysql als auch in sqlite, das typenlos ist.

erfahrungsgemäß funktioniert dies sehr schnell, wenn Sie nur Koordinaten speichern und die Koordinaten abrufen müssen, mit denen Sie rechnen können.

in php sehen diese 2 funktionen so aus

function LatitudeSmallToFloat($LatitudeSmall){
   if(($LatitudeSmall>0)&&($LatitudeSmall>>31)) 
     $LatitudeSmall=-(0x7FFFFFFF-($LatitudeSmall&0x7FFFFFFF))-1;
   return (float)$LatitudeSmall/(float)600000;
}

und wieder zurück:

function LatitudeFloatToSmall($LatitudeFloat){
   $Latitude=round((float)$LatitudeFloat*(float)600000);
   if($Latitude<0) $Latitude+=0xFFFFFFFF;
   return $Latitude;
}

Dies hat einen zusätzlichen Vorteil, wenn beispielsweise zwischengespeicherte eindeutige Schlüssel mit ganzen Zahlen erstellt werden. (Beispiel: um ein Geocode-Ergebnis zwischenzuspeichern). Hoffe, dies fügt der Diskussion einen Mehrwert hinzu.

Eine andere Anwendung könnte sein, wenn Sie ohne GIS-Erweiterungen sind und einfach ein paar Millionen dieser Lat/Lon-Paare behalten möchten. Sie können Partitionen in diesen Feldern in mysql verwenden, um von der Tatsache zu profitieren, dass es sich um Ganzzahlen handelt:

Create Table: CREATE TABLE `Locations` (
  `lat` int(10) unsigned NOT NULL,
  `lon` int(10) unsigned NOT NULL,
  `location` text,
  PRIMARY KEY (`lat`,`lon`) USING BTREE,
  KEY `index_location` (`locationText`(30))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY ()
PARTITIONS 100 */
2
Glenn Plas

In Vanilla Oracle erfordert die Funktion LOCATOR (eine verkrüppelte Version von Spatial), dass die Koordinatendaten mit dem Datentyp NUMBER (keine Genauigkeit) gespeichert werden. Wenn Sie versuchen, funktionsbasierte Indizes zu erstellen, um räumliche Abfragen zu unterstützen, wird dies andernfalls geknebelt.

2
Larry

Werfen Sie einen Blick auf die neuen Spatial-Datentypen, die in SQL Server 2008 eingeführt wurden. Sie wurden speziell für diese Art von Aufgaben entwickelt und machen das Indizieren und Abfragen der Daten wesentlich einfacher und effizienter.

http://msdn.Microsoft.com/en-us/library/bb933876 (v = sql.105) .aspx

http://blogs.technet.com/andrew/archive/2007/11/26/sql-server-2008-spatial-data-types.aspx

1

Ich würde eine Dezimalstelle mit der richtigen Genauigkeit für Ihre Daten verwenden.

1
Sam

Ich denke, es hängt von den Operationen ab, die Sie am häufigsten ausführen müssen.

Wenn Sie den vollständigen Wert als Dezimalzahl benötigen, verwenden Sie die Dezimalzahl mit der entsprechenden Genauigkeit und Skalierung. Float geht weit über Ihre Bedürfnisse hinaus, glaube ich.

Wenn Sie häufig in/von der Bruchnotation "degºmin'sec" konvertieren, würde ich in Betracht ziehen, jeden Wert als Ganzzahltyp zu speichern (smallint, tinyint, tinyint, smallint?).

1
jpj625