web-dev-qa-db-fra.com

Base de données / SQL: Comment stocker les données de longitude / latitude?

Question de performance ...

J'ai une base de données de maisons qui ont des données de géolocalisation (longitude et latitude).

Ce que je veux faire, c'est trouver la meilleure façon de stocker les données de localisation dans mon MySQL (v5.0.24a) en utilisant le moteur de base de données InnoDB afin que je puisse effectuer beaucoup de requêtes où je renvoie tous les enregistrements personnels qui se trouvent entre x1 et x2 latitude et y1 et y2 longitude.

En ce moment, mon schéma de base de données est

---------------------
Homes   
---------------------
geolat - Float (10,6)
geolng - Float (10,6)
---------------------

Et ma requête est:

SELECT ... 
WHERE geolat BETWEEN x1 AND x2
AND geolng BETWEEN y1 AND y2
  • Ce que j'ai décrit ci-dessus est-il le meilleur moyen de stocker les données de latitude et de longitude dans MySQL en utilisant Float (10,6) et en séparant la longitude/latitude? Sinon, c'est quoi? Il existe Float, Decimal et même Spatial comme type de données.
  • Est-ce la meilleure façon d'exécuter le SQL du point de vue des performances? Sinon, c'est quoi?
  • Est-il judicieux d'utiliser un moteur de base de données MySQL différent?

MISE À JOUR: toujours sans réponse

J'ai 3 réponses différentes ci-dessous. Une personne a dit d'utiliser Float. Une personne dit d'utiliser INT. Une personne dit d'utiliser Spatial.

J'ai donc utilisé l'instruction "EXPLAIN" de MySQL pour mesurer la vitesse d'exécution SQL. Il semble qu'il n'y ait absolument aucune différence dans l'exécution SQL (extraction de l'ensemble de résultats) si vous utilisez INT ou FLOAT pour le type de données de longitude et de latitude.

Il apparaît également que l'utilisation de l'instruction "BETWEEN" est beaucoup plus rapide que l'utilisation de l'instruction ">" ou "< "Instructions SQL. Il est presque 3 fois plus rapide d'utiliser" BETWEEN "que d'utiliser" >" et "< "déclaration.

Cela étant dit, je ne sais toujours pas quel serait l'impact sur les performances si vous utilisez Spatial car il n'est pas clair pour moi s'il est pris en charge avec ma version de MySQL en cours d'exécution (v5.0.24) ... ainsi que la façon dont je l'activer si elle est prise en charge .

Toute aide serait grandement appréciée

69
Timtom

float (10,6) est très bien.

Tout autre schéma de stockage alambiqué nécessitera plus de traduction vers l'intérieur et vers l'extérieur, et les calculs à virgule flottante sont très rapides.

29
richardtallent

Je sais que vous posez des questions sur MySQL, mais si les données spatiales sont importantes pour votre entreprise, vous voudrez peut-être reconsidérer. PostgreSQL + PostGIS sont également des logiciels libres, et ils ont une excellente réputation pour gérer efficacement les données spatiales et géographiques. Beaucoup de gens utilisent PostgreSQL uniquement à cause de PostGIS.

Je ne connais pas grand-chose sur le système spatial MySQL, alors peut-être qu'il fonctionne assez bien pour votre cas d'utilisation.

11
Jeff Davis

Le problème avec l'utilisation d'un autre type de données que "spatial" ici est que votre type de "sélection rectangulaire" peut (généralement, cela dépend de la luminosité de votre SGBD - et MySQL n'est certainement pas généralement le plus brillant) être optimisé en un seul seule dimension.

Le système peut choisir soit l'indice de longitude soit l'indice de latitude, et l'utiliser pour réduire l'ensemble de lignes à inspecter. Mais après cela, il y a le choix de: (a) récupérer toutes les lignes trouvées et les parcourir et tester pour "l'autre dimension", ou (b) faire le même processus sur "l'autre dimension" et ensuite faire correspondre ces deux jeux de résultats pour voir quelles lignes apparaissent dans les deux. Cette dernière option peut ne pas être implémentée en tant que telle dans votre moteur SGBD particulier.

Les index spatiaux font en quelque sorte ce dernier "automatiquement", donc je pense qu'il est sûr de dire qu'un index spatial donnera les meilleures performances dans tous les cas, mais il se peut également qu'il ne surpasse pas significativement les autres solutions, et que ça ne vaut pas la peine. Cela dépend de toutes sortes de choses comme le volume et la distribution de vos données réelles, etc., etc.

Il est certainement vrai que les index flottants (arborescents) sont nécessairement plus lents que les index entiers, en raison du temps généralement plus long nécessaire pour exécuter ">" sur les flottants que sur les entiers. Mais je serais surpris si cet effet était réellement perceptible.

6
Erwin Smout

Google utilise float (10,6) dans leur exemple "Store locator". Cela me suffit pour aller avec ça.

https://stackoverflow.com/a/5994082/1094271

De plus, à partir de MySQL 5.6.x, la prise en charge des extensions spatiales est bien meilleure et comparable à PostGIS en termes de fonctionnalités et de performances.

5
kouton

Je le stockerais sous forme d'entiers (int, 4 octets) représentés au 1/1 000 000ème degré. Cela vous donnerait une résolution de quelques pouces.

Je ne pense pas qu'il existe un type de données spatiales intrinsèque dans MySQL.

5
ZZ Coder

Flotteur (10,6)

Où est la latitude ou la longitude 5555.123456?

Vous ne voulez pas dire Float (9,6) à la place?

4
Sally

J'ai trouvé cette réponse utile, peut-être qu'elle peut aussi vous aider?: Problème de stockage des valeurs de latitude et de longitude dans la base de données MySQL

1
Elaine Marley

J'ai exactement le même schéma (float (10,6)) et la requête (sélection à l'intérieur d'un rectangle) et j'ai trouvé que la commutation du moteur db d'innoDB vers myisam doublait la vitesse pour une "recherche de point dans le rectangle" dans un tableau avec 780 000 enregistrements.

De plus, j'ai converti toutes les valeurs lng/lat en entiers cartésiens (x, y) et créé un index à deux colonnes sur les x, y et ma vitesse est passée de ~ 27 ms à 1,3 ms pour la même recherche.

1
ow3n

Cela dépend vraiment de la façon dont vous utilisez les données. Mais dans une simplification grossière des faits, la décimale est plus rapide mais moins précise en approximations. Plus d'infos ici:

http://msdn.Microsoft.com/en-us/library/aa223970 (SQL.80) .aspx

De plus, la norme pour les coordonnées GPS est spécifiée dans ISO 6709:

http://en.wikipedia.org/wiki/ISO_6709

0
AyexeM