Quelle est la différence entre POINT (X, Y) et GeomFromText («POINT (XY)»)?


17

Je voudrais stocker quelques positions géométriques dans ma base de données MySQL. Pour cela, j'utilise le type de données POINT. Presque partout, j'ai lu que la fonction GeomFromTextdevait être utilisée pour insérer des données dans le tableau.

Cependant, j'ai découvert que cela POINT(X,Y)fonctionne également. Je n'ai trouvé aucune description pourquoi GeomFromTextutiliser à la place de POINT.

Par exemple, j'ai la relation simple suivante:

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

Et je peux insérer des valeurs en utilisant les deux variantes suivantes:

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

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

Lorsque je vois la table ( SELECT * FROM Site), je vois le même blob binaire pour l'emplacement, et quand je vois les coordonnées ( SELECT *, AsText(Position) FROM Site), je vois aussi les mêmes valeurs.

Alors pourquoi utiliser GeomFromText? Existe-t-il des différences de performances (connues) entre ces deux variantes? Comment cela est-il résolu dans d'autres systèmes de base de données que MySQL?


Je ne sais pas s'il y a des différences de performances (je suppose que non, mais ce n'est qu'une supposition). Mais la deuxième approche serait plus simple lors de la conversion des valeurs de latitude et de longitude à partir d'une autre table. INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmpest plus simple que...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
ypercubeᵀᴹ

Je trouve également la deuxième variante beaucoup plus simple à construire, c'est pourquoi je me demande que généralement la première est utilisée presque partout où j'ai vu des extensions spatiales MySQL utilisées.
ComSubVie

J'ai juste essayé d'insérer 10 000 000 d'emplacements dans le tableau ci-dessus (sur mon hôte) en utilisant les deux variantes et je n'ai détecté aucune différence de performance mesurable.
ComSubVie

Veuillez envisager de réévaluer cela à la lumière de MySQL 8+ et pour la postérité: dba.stackexchange.com/a/227049/2639
Evan Carroll

Réponses:


16

Il existe deux formats binaires différents liés aux extensions spatiales MySQL, le format "bien connu binaire" (WKB) des normes et le GEOMETRYtype de données interne MySQL .

Avant MySQL 5.1.35, les fonctions comme POINT()ne renvoyaient pas le type de données interne MySQL; ils sont retournés WKB ... donc avant cela, vous deviez faire ceci:

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

Mais maintenant, comme dans votre exemple, cela fonctionne:

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

Au crédit des développeurs, lorsqu'ils ont changé Point()et des fonctions similaires pour retourner (plus sainement) des GEOMETRYobjets, ils ont autorisé GeomFromWKB()et des fonctions similaires à accepter réellement les données WKB ou MySQL Geometry en entrée, même si les fonctions sont destinées à accepter WKB en entrée.

Le fait que la 1ère méthode fonctionne (bien qu'elle soit techniquement erronée) sur les serveurs plus récents et que la 2ème méthode ne fonctionne pas du tout avant MySQL 5.1.35 pourrait expliquer pourquoi des exemples ont été écrits en utilisant l'approche que vous avez vue - pour éviter complètement le problème. Sinon ... je n'ai rien, ici.

La concaténation puis l'analyse du texte semblent intuitivement plus lentes et plus sujettes aux erreurs que les fonctions qui acceptent les variables appropriées en entrée, donc je ne vois aucune raison de créer des chaînes concaténées et d'utiliser les fonctions basées sur le texte.

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
Merci, intéressant que cela ne soit mentionné que comme une "note de bas de page" dans les notes de version et nulle part dans la documentation. Je vais donc rester à l'écart des méthodes basées sur le texte.
ComSubVie

1
Pourquoi 5 ans plus tard, les documents MySQL donnent toujours des exemples d'utilisation de la fonction ST_GeomFromText () lors de l'insertion? Cette réponse est-elle toujours pertinente? C'est un peu déroutant .. dev.mysql.com/doc/refman/5.7/en/populating-spatial-columns.html
Matt Kieran

1
@MattKieran WKB et WKT sont des formats normalisés et ouverts pour exprimer des données géospatiales. Les exemples les utilisent parce que les applications géospatiales axées sur les normes peuvent déjà contenir des données dans ces formats, permettant à MySQL d'accepter les géométries externes comme un seul argument ST_GeomFromText()et des fonctions de conversion similaires plutôt que d'exiger que les applications externes utilisent les fonctions SQL natives qui construisent des objets géométriques, qui se trouvent dans la référence de la fonction spatiale . Les documents pourraient être mieux organisés.
Michael - sqlbot

Aussi, @MattKieran, cette réponse n'est toujours pertinente que dans la mesure où elle explique pourquoi des exemples plus anciens peuvent être écrits contrairement à ce que les documents indiquent, pourquoi MySQL fonctionne avec les décalages de type apparents qu'utiliser les fonctions de cette manière semble indiquer. Les trois méthodes - les fonctions SQL natives, WKB (binaire) ou WKT (texte) - sont valides. Ce qui n'est plus nécessaire, c'est la conversion des valeurs de retour des fonctions natives de WKB, car leurs types de retour ne sont plus WKB comme il y a de nombreuses années.
Michael - sqlbot

4

MySQL 8+

Pour la postérité, la seule chose qui compte c'est que

  • Point(X,Y)est un constructeur pour les nombres avec précision et ne nécessite pas de convertir d'abord en texte pour le rendre plus rapide. Il est également garanti de RETOURNER POINTOU D'ÉCHEC . Cela le rend fortement typé si vous voulez y penser comme ça.
  • Constructeurs de texte bien connu (WKT) : ils sont toujours plus lents, car ils nécessitent une étape supplémentaire pour analyser le texte bien connu (WKT) . Notez que dans les anciennes versions, celles-ci pouvaient être trouvées sans le ST_préfixe; le cas échéant, utilisez la version avec le ST_préfixe. Utilisez les constructeurs WKT uniquement si votre entrée est déjà du texte connu. Sinon, utilisez le Point(x,y)constructeur ci-dessus.
    • ST_GeomFromText(wkt, srid)peut renvoyer N'IMPORTE QUEL type spatial pris en charge par MySQL et représenté par WKT. Cela le rend vaguement tapé si vous voulez y penser comme ça.
    • ST_PointFromText(wkt, srid)un POINTconstructeur fortement typé à partir d'un texte bien connu.

Clarté

Sauter la leçon d'histoire, ne le faites JAMAISGeomFromText(Point(x,y)) . C'est horrible, sans support et sans papiers.


-1

Avec GeomFromText ou toute autre fonction * FromText, vous pouvez spécifier le SRID . Je ne pense pas que vous puissiez le faire autrement.

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

Cela devrait être l'inverse, c'est- POINT(lng lat)à- dire au lieu dePOINT(lat lng)
Zishan

MySQL n'utilise de toute façon pas les SRID. C'est donc assez inutile. Si vous avez besoin de SRID, migrez vers PostgreSQL / PostGIS.
Evan Carroll

1
MySQL 8 utilise des SRID. En fait, j'ai des problèmes avec une base de données MySQL migrée de 5.7 à 8 précisément à cause des SRID.
cmoran92
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.