Chciałbym przechowywać pewne geometryczne pozycje w mojej bazie danych MySQL. W tym celu używam typu danych POINT. Niemal wszędzie czytam, że GeomFromText
należy użyć tej funkcji do wstawienia danych do tabeli.
Jednak dowiedziałem się, że to POINT(X,Y)
również działa. Nie znalazłem żadnego opisu, dlaczego GeomFromText
należy go użyć zamiast POINT
.
Na przykład mam następującą prostą relację:
CREATE TABLE Site (
SiteID BIGINT UNSIGNED,
Position POINT
);
I mogę wstawić wartości, używając następujących dwóch wariantów:
INSERT INTO Site (
1,
GeomFromText( 'POINT(48.19976 16.45572)' )
);
INSERT INTO Site (
2,
POINT(48.19976, 16.45572)
);
Kiedy przeglądam tabelę ( SELECT * FROM Site
), widzę ten sam binarny obiekt blob dla lokalizacji, a kiedy przeglądam współrzędne ( SELECT *, AsText(Position) FROM Site
), widzę te same wartości.
Dlaczego więc należy używać GeomFromText? Czy istnieją (znane) różnice w wydajności między tymi dwoma wariantami? Jak to rozwiązać w innych systemach baz danych niż MySQL?
źródło
INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmp
jest prostsze niż...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
Odpowiedzi:
Istnieją dwa różne formaty binarne związane z rozszerzeniami przestrzennymi MySQL, „dobrze znany format binarny” (WKB) ze standardów oraz wewnętrzny
GEOMETRY
typ danych MySQL .Przed MySQL 5.1.35 funkcje takie
POINT()
jak nie zwracały wewnętrznego typu danych MySQL; zwrócili WKB ... więc wcześniej trzeba było to zrobić:Ale teraz, jak w twoim przykładzie, działa to:
Na uznanie twórców, kiedy zmienili
Point()
funkcje podobne do (bardziej zdrowo) zwracanychGEOMETRY
obiektów, zezwoliliGeomFromWKB()
i podobne funkcje faktycznie akceptują dane WKB lub MySQL Geometry jako dane wejściowe, nawet jeśli funkcje mają przyjmować WKB jako dane wejściowe.Fakt, że pierwsza metoda działa (mimo że jest niepoprawna technicznie) na nowszych serwerach, a druga metoda wcale nie działa przed MySQL 5.1.35, może wyjaśniać, dlaczego przykłady zostały napisane przy użyciu podejścia, które widziałeś - całkowicie unikaj problemu. W przeciwnym razie ... Nie mam tu nic.
Łączenie, a następnie parsowanie tekstu wydaje się intuicyjnie wolniejsze i bardziej podatne na błędy niż funkcje, które akceptują odpowiednie zmienne jako dane wejściowe, więc nie mogę wymyślić żadnego powodu, aby tworzyć połączone łańcuchy i używać funkcji tekstowych.
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
źródło
ST_GeomFromText()
i podobnych funkcji konwersji, zamiast wymagać od zewnętrznych aplikacji używania natywnych funkcji SQL konstruujących obiekty geometryczne, które znajdują się w Spatial Function Reference . Dokumenty można lepiej zorganizować.MySQL 8+
Dla potomności liczy się tylko to
Point(X,Y)
jest konstruktorem liczb z precyzją i nie wymaga wcześniejszej konwersji na tekst, dzięki czemu jest szybszy. Gwarantowane jest również ZWROTPOINT
LUB USZKODZENIE . To sprawia, że jest mocno wpisany, jeśli chcesz o tym myśleć.ST_
prefiksu; jeśli jest dostępny, użyj wersji zST_
prefiksem. Konstruktorów WKT należy używać tylko wtedy, gdy wprowadzony tekst jest już dobrze znany. Jeśli nie, użyjPoint(x,y)
powyższego konstruktora.ST_GeomFromText(wkt, srid)
może zwrócić KAŻDY typ przestrzenny obsługiwany przez MySQL i reprezentowany przez WKT. To sprawia, że jest luźno wpisany, jeśli chcesz o tym myśleć.ST_PointFromText(wkt, srid)
mocno napisanyPOINT
konstruktor z dobrze znanego tekstu.Przejrzystość
Pomijając lekcję historii, NIGDY nie rób
GeomFromText(Point(x,y))
. To okropne, nieobsługiwane i nieudokumentowane.źródło
Za pomocą GeomFromText lub dowolnej innej funkcji * FromText możesz określić SRID . Nie sądzę, że możesz to zrobić inaczej.
źródło
POINT(lng lat)
ZamiastPOINT(lat lng)