¿Cuál es la diferencia entre POINT (X, Y) y GeomFromText ("POINT (XY)")?


17

Me gustaría almacenar algunas posiciones geométricas en mi base de datos MySQL. Para esto utilizo el tipo de datos POINT. Casi en todas partes leí que la función GeomFromTextdebería usarse para insertar datos en la tabla.

Sin embargo, descubrí que POINT(X,Y)también funciona. No encontré ninguna descripción de por qué GeomFromTextdebería usarse en lugar de POINT.

Por ejemplo, tengo la siguiente relación simple:

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

Y puedo insertar valores usando las siguientes dos variantes:

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

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

Cuando veo la tabla ( SELECT * FROM Site) veo el mismo blob binario para la ubicación, y cuando veo las coordenadas ( SELECT *, AsText(Position) FROM Site) también veo los mismos valores.

Entonces, ¿por qué se debe usar GeomFromText? ¿Existen diferencias de rendimiento (conocidas) entre estas dos variantes? ¿Cómo se resuelve esto en otros sistemas de bases de datos que MySQL?


No sé si hay diferencias de rendimiento (supongo que no, pero eso es solo una suposición). Pero el segundo enfoque sería más simple al convertir los valores de latitud y longitud de otra tabla. INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmpes más simple que...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
ypercubeᵀᴹ

También encuentro la segunda variante mucho más simple de construir, es por eso que me pregunto que, por lo general, la primera se usa en casi todas partes donde he visto usar extensiones espaciales de MySQL.
ComSubVie

Intenté insertar 10.000.000 de ubicaciones en la tabla anterior (en mi host) usando ambas variantes y no detecté ninguna diferencia de rendimiento medible.
ComSubVie

Considere reevaluar esto a la luz de MySQL 8+ y para la posteridad: dba.stackexchange.com/a/227049/2639
Evan Carroll

Respuestas:


16

Existen dos formatos binarios diferentes relacionados con las extensiones espaciales de MySQL, el formato "binario conocido" (WKB) de los estándares y el GEOMETRYtipo de datos interno de MySQL .

Antes de MySQL 5.1.35, funciones como POINT()no devolvían el tipo de datos interno de MySQL; devolvieron WKB ... así que antes de eso, tenías que hacer esto:

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

Pero ahora, como en su ejemplo, esto funciona:

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

Para el crédito de los desarrolladores, cuando cambiaron Point()y funciones similares para (más sensatamente) devolver GEOMETRYobjetos, permitieron que GeomFromWKB()funciones similares aceptaran datos de geometría WKB o MySQL como entrada, aunque las funciones están destinadas a aceptar WKB como entrada.

El hecho de que el primer método funcione (a pesar de ser técnicamente incorrecto) en servidores más nuevos y el segundo método no funcione antes de MySQL 5.1.35 podría explicar por qué los ejemplos se escribieron utilizando el enfoque que ha visto. evitar el problema por completo. De lo contrario ... no tengo nada, aquí.

Concatenar y luego analizar el texto parece intuitivamente más lento y más propenso a errores que las funciones que aceptan las variables adecuadas como entrada, por lo que no puedo pensar en ningún motivo para crear cadenas concatenadas y usar las funciones basadas en texto.

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
Gracias, interesante que esto solo se menciona como una "nota al pie" en las notas de la versión y en ninguna parte de la documentación. Así que me mantendré alejado de los métodos basados ​​en texto.
ComSubVie

1
¿Por qué 5 años después, los documentos de MySQL siguen dando ejemplos del uso de la función ST_GeomFromText () al insertar? ¿Sigue siendo relevante esta respuesta? Es un poco confuso .. dev.mysql.com/doc/refman/5.7/en/populating-spatial-columns.html
Matt Kieran

1
@MattKieran WKB y WKT son formatos abiertos estandarizados para expresar datos geoespaciales. Los ejemplos los usan porque las aplicaciones geoespaciales orientadas a estándares ya pueden contener datos en estos formatos, lo que permite a MySQL aceptar geometrías externas como un argumento único ST_GeomFromText()y funciones de conversión similares en lugar de requerir que las aplicaciones externas usen las funciones SQL nativas que construyen objetos de geometría, que se encuentran en la Referencia de funciones espaciales . Los documentos podrían estar mejor organizados.
Michael - sqlbot

También @MattKieran, esta respuesta solo es relevante en el sentido de que explica por qué los ejemplos más antiguos pueden escribirse en contra de lo que indican los documentos, y por qué MySQL funciona con los aparentes desajustes de tipo que parece indicar el uso de las funciones de esta manera. Los tres métodos (las funciones nativas de SQL, WKB (binario) o WKT (texto)) son válidos. Lo que ya no se necesita es convertir los valores de retorno de la función nativa de WKB, porque sus tipos de retorno ya no son WKB como lo fueron hace muchos años.
Michael - sqlbot

4

MySQL 8+

Para la posteridad lo único que importa es

  • Point(X,Y)es un constructor de números con precisión y no requiere conversión primero a texto, lo que lo hace más rápido. También se garantiza DEVOLVER A POINTO FALLAR . Esto lo hace fuertemente tipado si quieres pensarlo así.
  • Constructores de texto conocido (WKT) : estos son siempre más lentos, ya que requieren un paso adicional para analizar el texto conocido (WKT) . Tenga en cuenta que en versiones anteriores se pueden encontrar sin el ST_prefijo; donde esté disponible, use la versión con el ST_prefijo. Utilice los constructores WKT solo si su entrada ya es texto conocido. Si no, use el Point(x,y)constructor anterior.
    • ST_GeomFromText(wkt, srid)puede devolver CUALQUIER tipo espacial que sea compatible con MySQL y pueda ser representado por WKT. Esto hace que esté tipeado libremente si quieres pensarlo así.
    • ST_PointFromText(wkt, srid)un POINTconstructor fuertemente tipado de texto conocido.

Claridad

Saltarse la lección de historia, NUNCA lo haga GeomFromText(Point(x,y)). Eso es horrible, sin apoyo e indocumentado.


-1

Con GeomFromText o cualquier otra función * FromText puede especificar el SRID . No creo que puedas hacerlo de otra manera.

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

Esto debería ser al revés, es decir, en POINT(lng lat)lugar dePOINT(lat lng)
Zishan

MySQL no usa SRID de todos modos. Eso es bastante inútil. Si necesita SRID, migre a PostgreSQL / PostGIS.
Evan Carroll

1
MySQL 8 usa SRID. De hecho, estoy teniendo problemas con una base de datos MySQL migrada de 5.7 a 8 precisamente debido a los SRID.
cmoran92
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.