it-swarm.com.de

Datenbank / SQL: Wie werden Längen- / Breitengraddaten gespeichert?

Leistungsfrage ...

Ich habe eine Datenbank mit Häusern mit Geolokalisierungsdaten (Längen- und Breitengrad).

Ich möchte den besten Weg finden, um die Standortdaten in MySQL (v5.0.24a) mithilfe der InnoDB-Datenbank-Engine zu speichern, damit ich eine Vielzahl von Abfragen durchführen kann, bei denen ich alle Stammdatensätze zurückgebe, die sich zwischen diesen befinden x1 und x2 latitude und y1 und y2 longitude.

Im Moment ist mein Datenbankschema

---------------------
Homes   
---------------------
geolat - Float (10,6)
geolng - Float (10,6)
---------------------

Und meine Frage ist:

SELECT ... 
WHERE geolat BETWEEN x1 AND x2
AND geolng BETWEEN y1 AND y2
  • Ist das, was ich oben beschrieben habe, der beste Weg, um die Breiten- und Längengraddaten in MySQL mit Float (10,6) zu speichern und Längengrad/Breitengrad zu trennen? Wenn nicht, was ist das? Es gibt Float, Decimal und sogar Spatial als Datentyp.
  • Ist dies der beste Weg, um SQL unter Performance-Gesichtspunkten durchzuführen? Wenn nicht, was ist das?
  • Ist die Verwendung einer anderen MySQL-Datenbank-Engine sinnvoll?

PDATE: Noch nicht beantwortet

Ich habe 3 verschiedene Antworten unten. Eine Person sagt, sie soll Float benutzen. Eine Person sagt, sie soll INT verwenden. Eine Person sagt, sie soll Spatial benutzen.

Daher habe ich die SQL-Ausführungsgeschwindigkeit mit der MySQL-Anweisung "EXPLAIN" gemessen. Es scheint absolut keinen Unterschied in der SQL-Ausführung (Abrufen der Ergebnismenge) zu geben, wenn INT oder FLOAT für den Längen- und Breitengrad-Datentyp verwendet wird.

Es scheint auch, dass die Verwendung der Anweisung "BETWEEN" bedeutend schneller ist als die Verwendung der Anweisung ">" oder "< "SQL-Anweisungen. Die Verwendung von" BETWEEN "ist fast dreimal schneller als die Verwendung von" >" und "<" Erklärung.

Abgesehen davon bin ich immer noch nicht sicher, wie sich die Leistung bei der Verwendung von Spatial auswirken würde, da mir nicht klar ist, ob es mit meiner Version von MySQL (v5.0.24) unterstützt wird und wie ich es aktiviere, wenn es unterstützt wird .

Jede Hilfe wäre sehr dankbar

69
Timtom

float (10,6) ist in Ordnung.

Alle anderen verschachtelten Speichersysteme erfordern mehr Ein- und Ausgangskonvertierungen, und Gleitkomma-Mathematik ist schnell genug.

29
richardtallent

Ich weiß, dass Sie nach MySQL fragen, aber wenn räumliche Daten für Ihr Unternehmen wichtig sind, sollten Sie es sich vielleicht noch einmal überlegen. PostgreSQL + PostGIS sind ebenfalls freie Software und genießen einen hervorragenden Ruf bei der effizienten Verwaltung von räumlichen und geografischen Daten. Viele Leute benutzen PostgreSQL nur wegen PostGIS.

Ich weiß jedoch nicht viel über das räumliche MySQL-System, daher funktioniert es möglicherweise gut genug für Ihren Anwendungsfall.

11
Jeff Davis

Das Problem bei der Verwendung eines anderen Datentyps als "räumlich" ist, dass Ihre Art der "rechteckigen Auswahl" (in der Regel hängt dies davon ab, wie hell Ihr DBMS ist - und MySQL ist sicherlich nicht die hellste) nur in einem optimiert werden kann einzelne Dimension.

Das System kann entweder den Längengradindex oder den Breitengradindex auswählen und damit die Anzahl der zu überprüfenden Zeilen verringern. Nachdem dies geschehen ist, haben Sie die Wahl: (a) alle gefundenen Zeilen abzurufen und über diese zu scannen und auf die "andere Dimension" zu prüfen, oder (b) den ähnlichen Vorgang in der "anderen Dimension" und anschließend Vergleichen Sie diese beiden Ergebnismengen, um zu sehen, welche Zeilen in beiden angezeigt werden. Diese letztere Option ist möglicherweise nicht als solche in Ihrer speziellen DBMS-Engine implementiert.

Bei räumlichen Indizes geschieht dies "automatisch". Daher kann man davon ausgehen, dass ein räumlicher Index in jedem Fall die beste Leistung erbringt. Es kann jedoch auch vorkommen, dass er die anderen Lösungen nicht wesentlich übertrifft dass es die Mühe einfach nicht wert ist. Dies hängt von allerlei Dingen ab, wie dem Volumen und der Verteilung in Ihren tatsächlichen Daten usw. usw.

Es ist sicher richtig, dass float (tree) -Indizes notwendigerweise langsamer sind als Integer-Indizes, da die Ausführung von '>' für floats normalerweise länger dauert als für Integer-Indizes. Es würde mich aber wundern, wenn dieser Effekt tatsächlich spürbar wäre.

6
Erwin Smout

Google verwendet float (10,6) in seinem Beispiel "Store Locator". Das reicht mir, um mitzumachen.

https://stackoverflow.com/a/5994082/1094271

Ab MySQL 5.6.x ist die Unterstützung für räumliche Erweiterungen viel besser und hinsichtlich Funktionen und Leistung mit PostGIS vergleichbar.

5
kouton

Ich würde es als ganze Zahlen (int, 4-Byte) speichern, die in 1/1,000,000th Graden dargestellt werden. Das würde Ihnen eine Auflösung von wenigen Zoll geben.

Ich glaube nicht, dass es in MySQL einen intrinsischen räumlichen Datentyp gibt.

5
ZZ Coder

Schwimmer (10,6)

Wo liegt der Breitengrad oder der Längengrad 5555.123456?

Meinst du nicht stattdessen Float (9,6)?

4
Sally

Ich fand diese Antwort nützlich, vielleicht kann sie Ihnen auch helfen ?: Problem beim Speichern der Breiten- und Längengrade in der MySQL-Datenbank

1
Elaine Marley

Ich habe genau dasselbe Schema (float (10,6)) und dieselbe Abfrage (Auswahl innerhalb eines Rechtecks) und ich habe festgestellt, dass das Umschalten der Datenbank-Engine von innoDB auf myisam die Geschwindigkeit für ein "Point-in-Rectangle-Lookup" in einer Tabelle verdoppelt hat mit 780.000 Datensätzen.

Außerdem habe ich alle lng/lat-Werte in kartesische Ganzzahlen (x, y) konvertiert und einen zweispaltigen Index für x, y erstellt, und meine Geschwindigkeit wurde für dieselbe Suche von ~ 27 ms auf 1,3 ms erhöht.

1
ow3n

Es hängt wirklich davon ab, wie Sie die Daten verwenden. Bei einer groben Vereinfachung der Tatsachen ist die Dezimalstelle schneller, bei Approximationen jedoch ungenauer. Mehr Infos hier:

http://msdn.Microsoft.com/en-us/library/aa223970 (SQL.80) .aspx

Der Standard für GPS-Koordinaten ist in ISO 6709 festgelegt:

http://en.wikipedia.org/wiki/ISO_6709

0
AyexeM