Qual è la differenza tra POINT (X, Y) e GeomFromText (“POINT (XY)”)?


17

Vorrei memorizzare alcune posizioni geometriche nel mio database MySQL. Per questo utilizzo il tipo di dati POINT. Quasi ovunque leggo che la funzione GeomFromTextdovrebbe essere utilizzata per inserire dati nella tabella.

Tuttavia, ho scoperto che POINT(X,Y)funziona anche. Non ho trovato alcuna descrizione del motivo per cui GeomFromTextdovrebbe essere utilizzato invece di POINT.

Ad esempio ho la seguente semplice relazione:

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

E posso inserire valori usando le seguenti due varianti:

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

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

Quando visualizzo la tabella ( SELECT * FROM Site) vedo lo stesso BLOB binario per la posizione e quando visualizzo le coordinate ( SELECT *, AsText(Position) FROM Site) vedo anche gli stessi valori.

Quindi perché usare GeomFromText? Ci sono differenze di prestazioni (conosciute) tra queste due varianti? Come viene risolto in altri sistemi di database diversi da MySQL?


Non so se ci siano differenze di prestazioni (immagino di no, ma è solo un'ipotesi). Ma il secondo approccio sarebbe più semplice quando si convertono i valori di latitudine e longitudine da un'altra tabella. INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmpè più semplice di...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
ypercubeᵀᴹ

Trovo anche la seconda variante molto più semplice da costruire, ecco perché mi chiedo che di solito la prima venga utilizzata quasi ovunque dove ho visto le estensioni spaziali MySQL utilizzate.
ComSubVie,

Ho appena provato a inserire 10.000.000 di posizioni nella tabella sopra (sul mio host) utilizzando entrambe le varianti e non ho rilevato alcuna differenza di prestazioni misurabile.
ComSubVie,

Si prega di considerare di rivalutare questo alla luce di MySQL 8+ e per i posteri: dba.stackexchange.com/a/227049/2639
Evan Carroll

Risposte:


16

Esistono due diversi formati binari relativi alle estensioni spaziali MySQL, il formato "ben noto binario" (WKB) dagli standard e il GEOMETRYtipo di dati interno MySQL .

Prima di MySQL 5.1.35, funzioni come POINT()non restituivano il tipo di dati interno MySQL; hanno restituito WKB ... quindi prima di allora, dovevi farlo:

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

Ma ora, come nel tuo esempio, questo funziona:

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

A credito degli sviluppatori, quando hanno cambiato Point()e funzioni simili a (più saggiamente) restituiscono GEOMETRYoggetti, hanno permesso GeomFromWKB()e funzioni simili di accettare effettivamente dati WKB o MySQL Geometry come input anche se le funzioni intendono accettare WKB come input.

Il fatto che il 1o metodo funzioni (nonostante sia tecnicamente sbagliato) su server più recenti e il 2o metodo non funziona affatto prima di MySQL 5.1.35 potrebbe spiegare perché gli esempi sono stati scritti usando l'approccio che hai visto evitare del tutto il problema. Altrimenti ... Non ho niente, qui.

Concatenare e quindi analizzare il testo sembra intuitivamente più lento e più soggetto a errori rispetto alle funzioni che accettano le variabili appropriate come input, quindi non riesco a pensare a nessun motivo per creare stringhe concatenate e utilizzare le funzioni basate sul testo.

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


1
Grazie, interessante che questo è menzionato solo come "nota a piè di pagina" nelle note di rilascio e da nessuna parte nella documentazione. Quindi starò lontano dai metodi basati sul testo.
ComSubVie,

1
Perché 5 anni dopo i documenti MySQL forniscono ancora esempi sull'uso della funzione ST_GeomFromText () durante l'inserimento? Questa risposta è ancora pertinente? È un po 'confuso .. dev.mysql.com/doc/refman/5.7/it/populating-spatial-columns.html
Matt Kieran

1
@MattKieran WKB e WKT sono formati aperti standardizzati per esprimere dati geospaziali. Gli esempi li usano perché le applicazioni geospaziali orientate agli standard potrebbero già contenere dati in questi formati, consentendo a MySQL di accettare geometrie esterne come singolo argomento ST_GeomFromText()e funzioni di conversione simili anziché richiedere ad applicazioni esterne di utilizzare le funzioni SQL native che costruiscono oggetti geometrici, che si trovano nel riferimento alle funzioni spaziali . I documenti potrebbero essere organizzati meglio.
Michael - sqlbot

Anche @MattKieran questa risposta è ancora rilevante solo nel senso che spiega perché esempi più vecchi possano essere scritti in contrasto con ciò che indicano i documenti, qualsiasi motivo per cui MySQL funzioni con il tipo apparente non corrisponde al fatto che l'utilizzo delle funzioni in questo modo sembrerebbe indicare. Tutti e tre i metodi - le funzioni SQL native, WKB (binario) o WKT (testo) - sono validi. Ciò che non è più necessario è la conversione dei valori restituiti dalla funzione nativa da WKB, poiché i loro tipi di restituzione non sono più WKB come lo erano molti anni fa.
Michael - sqlbot

4

MySQL 8+

Per i posteri l'unica cosa che conta

  • Point(X,Y)è un costruttore di numeri con precisione e non richiede la prima conversione in testo rendendolo più veloce. È inoltre garantito il RESO A POINTO FAIL . Questo lo rende fortemente tipizzato se vuoi pensarlo in quel modo.
  • Costruttori di testi ben noti (WKT) : sono sempre più lenti, poiché richiedono un passaggio aggiuntivo per analizzare il testo ben noto (WKT) . Nota nelle versioni precedenti queste potrebbero essere trovate senza il ST_prefisso; ove disponibile, utilizzare la versione con il ST_prefisso. Usa i costruttori WKT solo se il tuo input è già noto. In caso contrario, utilizzare il Point(x,y)costruttore sopra.

Chiarezza

Saltare la lezione di storia, MAI farlo GeomFromText(Point(x,y)). È orribile, non supportato e non documentato.


-1

Con GeomFromText o qualsiasi altra funzione * FromText è possibile specificare SRID . Non penso che tu possa farlo diversamente.

PointFromText('POINT(lat lng)', 4326)

Questo dovrebbe essere il contrario, ovvero POINT(lng lat)anzichéPOINT(lat lng)
Zishan,

MySQL non utilizza comunque SRID. Quindi è abbastanza inutile. Se hai bisogno di SRID, esegui la migrazione a PostgreSQL / PostGIS.
Evan Carroll,

1
MySQL 8 utilizza SRID. In effetti, sto riscontrando problemi con un DB MySQL migrato da 5,7 a 8 proprio a causa degli SRID.
cmoran92,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.