Was ist der Unterschied zwischen POINT (X, Y) und GeomFromText („POINT (XY)“)?

17

Ich möchte einige geometrische Positionen in meiner MySQL-Datenbank speichern. Dafür verwende ich den Datentyp POINT. Fast überall las ich, dass die Funktion GeomFromTextverwendet werden sollte, um Daten in die Tabelle einzufügen.

Ich fand jedoch heraus, dass das POINT(X,Y)auch funktioniert. Ich habe keine Beschreibung gefunden, warum statt GeomFromTextverwendet werden sollte POINT.

Zum Beispiel habe ich die folgende einfache Beziehung:

CREATE TABLE Site (
    SiteID      BIGINT UNSIGNED,
    Position    POINT
);

Und ich kann Werte mit den folgenden zwei Varianten einfügen:

INSERT INTO Site (
    1,
    GeomFromText( 'POINT(48.19976 16.45572)' )
);

INSERT INTO Site (
    2,
    POINT(48.19976, 16.45572)
);

Wenn ich die Tabelle ansehe ( SELECT * FROM Site), sehe ich den gleichen binären Blob für die Position, und wenn ich die Koordinaten ansehe ( SELECT *, AsText(Position) FROM Site), sehe ich auch die gleichen Werte.

Warum sollte GeomFromText verwendet werden? Gibt es (bekannte) Leistungsunterschiede zwischen diesen beiden Varianten? Wie wird dies in anderen Datenbanksystemen als MySQL gelöst?

ComSubVie
quelle
Ich weiß nicht, ob es irgendwelche Leistungsunterschiede gibt (ich würde nicht raten, aber das ist nur eine Vermutung). Der zweite Ansatz wäre jedoch einfacher, wenn Breiten- und Längengrade aus einer anderen Tabelle konvertiert würden. INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmpist einfacher als...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
ypercubeᵀᴹ
Ich finde auch die zweite Variante viel einfacher zu konstruieren, deshalb wundere ich mich, dass normalerweise die erste fast überall verwendet wird, wo räumliche MySQL-Erweiterungen verwendet werden.
ComSubVie
Ich habe gerade versucht, 10.000.000 Standorte in der obigen Tabelle (auf meinem Host) unter Verwendung beider Varianten einzufügen, und habe keinen messbaren Leistungsunterschied festgestellt.
ComSubVie
Bitte überlegen Sie, dies im Lichte von MySQL 8+ und für die Nachwelt neu zu bewerten: dba.stackexchange.com/a/227049/2639
Evan Carroll

Antworten:

16

Es gibt zwei verschiedene Binärformate für die räumlichen Erweiterungen von MySQL, das aus den Standards bekannte Binärformat (WKB) und den internen MySQL- GEOMETRYDatentyp.

Vor MySQL 5.1.35 funktioniert das wie POINT() den internen MySQL-Datentyp nicht zurückgegeben. Sie haben WKB zurückgegeben. Vorher mussten Sie Folgendes tun:

INSERT INTO t1 (pt_col) VALUES (GeomFromWKB(Point(1,2)));

Aber jetzt, wie in Ihrem Beispiel, funktioniert Folgendes:

INSERT INTO t1 (pt_col) VALUES(Point(1,2));

Zum Wohle der Entwickler, wenn sie sich geändert haben Point() und ähnliche Funktionen verwenden, um GEOMETRYObjekte (sicherer) zurückzugeben , können sie GeomFromWKB()WKB- oder MySQL-Geometriedaten als Eingabe akzeptieren, obwohl die Funktionen WKB als Eingabe akzeptieren sollen.

Die Tatsache, dass die 1. Methode (obwohl technisch falsch) auf neueren Servern funktioniert und die 2. Methode vor MySQL 5.1.35 überhaupt nicht funktioniert könnte erklären, warum Beispiele mit dem von Ihnen Ansatz geschrieben wurden Vermeiden Sie das Problem vollständig. Ansonsten ... ich habe hier nichts.

Das Verketten und anschließende Parsen von Text scheint intuitiv langsamer und fehleranfälliger zu sein als Funktionen, die korrekte Variablen als Eingabe akzeptieren. Daher kann ich mir keinen Grund vorstellen, verkettete Zeichenfolgen zu erstellen und die textbasierten Funktionen zu verwenden.

http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-wkb-functions

http://dev.mysql.com/doc/relnotes/mysql/5.1/en/news-5-1-35.html

Michael - sqlbot
quelle
1
Danke, interessant, dass dies nur als "Fußnote" in den Release Notes und nirgendwo in der Dokumentation erwähnt wird. Also werde ich mich von den textbasierten Methoden fernhalten.
ComSubVie
1
Warum geben die MySQL-Dokumente 5 Jahre später noch Beispiele für die Verwendung der Funktion ST_GeomFromText () beim Einfügen? Ist diese Antwort noch relevant? Es ist ein bisschen verwirrend. Dev.mysql.com/doc/refman/5.7/en/populating-spatial-columns.html
Matt Kieran
1
@MattKieran WKB und WKT sind standardisierte, offene Formate zur Darstellung von Geodaten. Die Beispiele verwenden sie, da standardorientierte Geodatenanwendungen möglicherweise bereits Daten in diesen Formaten enthalten, sodass MySQL externe Geometrien als einziges Argument für ST_GeomFromText()und ähnliche Konvertierungsfunktionen akzeptieren kann, anstatt dass externe Anwendungen die systemeigenen SQL-Funktionen zum Erstellen von Geometrieobjekten verwenden müssen finden Sie in der Raumfunktionsreferenz . Die Dokumente könnten besser organisiert werden.
Michael - Sqlbot
Auch @MattKieran ist diese Antwort nur insofern noch relevant, als sie erklärt, warum ältere Beispiele möglicherweise anders geschrieben sind als in den Dokumenten angegeben, und warum MySQL mit den offensichtlichen Typenkonflikten arbeitet, auf die die Verwendung der Funktionen auf diese Weise hindeutet. Alle drei Methoden - die nativen SQL-Funktionen WKB (binär) oder WKT (Text) - sind gültig. Was nicht mehr benötigt wird, ist die Konvergenz der nativen Funktionsrückgabewerte von WKB, da deren Rückgabetypen nicht mehr wie vor vielen Jahren WKB sind.
Michael - Sqlbot
4

MySQL 8+

Für die Nachwelt das Einzige, worauf es ankommt

  • Point(X,Y)ist ein Konstruktor für Zahlen mit Präzision und erfordert keine Konvertierung in Text, um diese schneller zu machen. Es ist auch garantiert, A oder POINTFAIL RÜCKZUFÜHREN . Dies macht es stark getippt, wenn Sie so darüber nachdenken möchten.
  • Well-Known Text (WKT) Bauer: Das ist immer langsamer, da sie einen Additionsschritt erfordern die analysieren Well-Known Text (WKT) . Beachten Sie, dass in älteren Versionen diese ohne das ST_Präfix gefunden werden können . Verwenden Sie, sofern verfügbar, die Version mit dem ST_Präfix. Verwenden Sie die WKT-Konstruktoren nur, wenn Ihre Eingabe bereits bekannter Text ist. Wenn nicht, benutze den Point(x,y)obigen Konstruktor.
    • ST_GeomFromText(wkt, srid)kann JEDEN räumlichen Typ zurückgeben, der von MySQL unterstützt und von WKT dargestellt wird. Dies macht es lose getippt, wenn Sie so darüber nachdenken möchten.
    • ST_PointFromText(wkt, srid)ein stark typisierter POINTKonstruktor aus bekanntem Text.

Klarheit

Überspringen der Geschichtsstunde, nie tun GeomFromText(Point(x,y)). Das ist schrecklich, nicht unterstützt und ohne Papiere.

Evan Carroll
quelle
-1

Mit GeomFromText oder einer anderen * FromText-Funktion können Sie die SRID angeben . Ich glaube nicht, dass Sie es anders machen können.

PointFromText('POINT(lat lng)', 4326)
fromvega
quelle
Dies sollte umgekehrt sein, dh POINT(lng lat)anstelle vonPOINT(lat lng)
Zishan
MySQL verwendet sowieso keine SRIDs. Das ist also ziemlich nutzlos. Wenn Sie SRIDs benötigen, migrieren Sie zu PostgreSQL / PostGIS.
Evan Carroll
1
MySQL 8 verwendet SRIDs. Tatsächlich habe ich Probleme mit einer MySQL-Datenbank, die genau aufgrund von SRIDs von 5.7 auf 8 migriert wurde.
cmoran92