Quel est le type de données idéal à utiliser lors du stockage de la latitude / longitude dans une base de données MySQL?

432

Sachant que je vais effectuer des calculs sur des paires lat / longues, quel type de données convient le mieux à une utilisation avec une base de données MySQL?

Codebeef
la source
1
J'ai trouvé ce lien très utile: howto-use-mysql-spatial-ext.blogspot.com/2007/11/… Il peut être un peu plus ancien, mais il contient une explication complète comprenant des exemples.
madc
À mon humble avis, la plupart des gens ici ne comprennent pas ce qui se passe. Dès que le code de l'application touche un nombre, à condition que l'on utilise des doubles (ce que la plupart font), le nombre devient au plus une double précision . Le stocker alors avec même un million de décimales ne servira à rien. Le stocker avec un nombre limité de décimales (par exemple 6) détruit une partie de cette précision et ajoute une erreur accumulée chaque fois qu'il est réécrit dans la base de données . Un double porte environ 16 nombres significatifs, potentiellement tous décimaux. La suppression de 10 d'entre eux crée une erreur accumulée au fil du temps. C'est "virgule flottante" pour raison. Cont.
Stormwind
Cont: 6 décimales peuvent être correctes lors du stockage d'un chiffre tel qu'il a été acquis d'une source externe, inchangé et pour la première fois - en tant que matériau source. Mais si vous effectuez un calcul une seule fois et que vous le stockez à nouveau, il est stupide de supprimer une partie de sa précision en appliquant un format décimal spécifique. Effectuer le calcul uniquement à l'intérieur du serveur peut être différent (le serveur peut ou non utiliser autre chose que doubler en interne), et utiliser des représentations numériques pires que doubler dans le calcul de l'application dec diminue le besoin de précision de stockage également.
Stormwind
Cont: SI le serveur stocke le nombre avec une précision plus élevée , malgré le "9.6" revendiqué (ce que je ne sais pas si c'est le cas), alors rien de tout cela n'a d'importance, et le format est purement une question de commodité - a peu à faire avec des problèmes de précision. Mais je ne serais pas surpris si le serveur arrondit réellement n'importe quel nombre en précision 6 décimales avec ce format.
Stormwind
Cont: Enfin: Pour lat, lon's, la 6ème décimale est une question de rupture dans un ca. Grille de 11 centimètres. Chaque fois que l'on lit (touche), calcule et mémorise à nouveau, avec 6 décimales, il y aura un nouveau claquage (= erreur cumulée). Si toutes les erreurs se produisent dans le même sens, il y aura une grosse erreur. Si vous effectuez des multiplications temporaires sur celui-ci (par exemple, augmenter, puis soustraire et réduire), il peut devenir encore plus grand. Ne perdez pas la précision sans un bon rason!
Stormwind

Réponses:

161

Utilisez les extensions spatiales de MySQL avec SIG.

Kirk Strauser
la source
25
Avez-vous d'autres liens vers des exemples ou d'autres informations sur la meilleure façon de commencer avec eux?
Codebeef
6
MYSQL Spatial est une bonne option, mais a toujours des limites et des mises en garde importantes (à partir de 6). Veuillez voir ma réponse ci-dessous ...
James Schek
1
@James Schek a raison. De plus, MySQL fait tous ses calculs en utilisant la géométrie euclidienne, donc il ne représente pas un cas d'utilisation réel pour lat / lng.
mkuech
FYI; Mysql ne prend en charge l'index spatial qu'avec les tables * .myisam, c'est-à-dire le moteur ISAM. Lien: dev.mysql.com/doc/refman/5.0/en/creating-spatial-indexes.html
PodTech.io
Jetez un œil à cet article dans la dernière partie Mise à jour: mysqlserverteam.com/mysql-5-7-and-gis-an-example
Jaspal Singh
150

Google fournit une solution de début à la fin PHP / MySQL pour un exemple d'application "Store Locator" avec Google Maps. Dans cet exemple, ils stockent les valeurs lat / lng comme "Float" avec une longueur de "10,6"

http://code.google.com/apis/maps/articles/phpsqlsearch.html

Ted Avery
la source
11
Google ne comprend clairement pas comment fonctionne la spécification FLOAT: FLOAT(10,6)laisse 4 chiffres pour la partie entière des coordonnées. Et non, le signe ne compte pas - cela vient de l'attribut (non) signé.
Alix Axel
2
Mais si vous devez stocker en tant que partie intégrante, les valeurs de [0, 180] devraient être plus que suffisantes, non?
Hrvoje Golcic
37
@AlixAxel Je pense que Google sait ce qu'il fait. Parce qu'il indique que: " Avec les capacités de zoom actuelles de Google Maps, vous ne devriez avoir besoin que de 6 chiffres de précision après la décimale. Cela permettra aux champs de stocker 6 chiffres après la décimale, plus jusqu'à 4 chiffres avant la décimale, par exemple - 123,456789 degrés. ". Si non signé est coché, le modèle sera 1234,567890 . Donc pas de problèmes.
1.44mb
16
@AlixAxel Il compte les nombres dans la séquence; n'utilisant pas de coordonnées réelles ...
Andrew Ellis
8
Utilisation du type Doublede données pour Laravel
FooBar
134

Fondamentalement, cela dépend de la précision dont vous avez besoin pour vos emplacements. En utilisant DOUBLE, vous aurez une précision de 3,5 nm. DECIMAL (8,6) / (9,6) descend à 16 cm. FLOTTEUR mesure 1,7 m ...

Ce tableau très intéressant a une liste plus complète: http://mysql.rjweb.org/doc.php/latlng :

Datatype               Bytes            Resolution

Deg*100 (SMALLINT)     4      1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5      1570 m    1.0 mi  Cities
SMALLINT scaled        4       682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6        16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7        16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6       2.7 m    8.8 ft
FLOAT                  8       1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9        16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8        16mm    5/8 in  Marbles
DOUBLE                16       3.5nm     ...    Fleas on a dog

J'espère que cela t'aides.

Simon
la source
2
Je dois écrire un commentaire constructif et détaillé axé sur le contenu des messages, donc je dirai qu'en observant le tableau de précision fourni par le site Web de Rick James, j'ai été légèrement amusé par la description de la résolution "puces sur un chien" et le sentait digne de félicitations. Techniquement parlant, ce fut une description utile qui m'a aidé à décider quel type de données utiliser lors du stockage des coordonnées pour mesurer la distance entre deux adresses, que @Simon, je voudrais vous remercier pour le partage.
Sam_Butler
FWIW, l'utilisation par ce lien de "SMALLINT scaled" est terriblement inefficace. La réponse d'Oguzhan est un excellent moyen de stocker le long / lat avec 7 chiffres après le point décimal, dans un entier signé de 4 octets. Grande précision (~ 1cm) dans une petite taille (4B).
ToolmakerSteve
74

Les extensions spatiales de MySQL sont la meilleure option car vous avez la liste complète des opérateurs spatiaux et des indices à votre disposition. Un index spatial vous permettra d'effectuer très rapidement des calculs basés sur la distance. N'oubliez pas qu'à partir de la version 6.0, l'extension spatiale est toujours incomplète. Je ne mets pas fin à MySQL Spatial, je ne fais que vous informer des pièges avant d'aller trop loin.

Si vous traitez strictement des points et seulement la fonction DISTANCE, c'est très bien. Si vous devez effectuer des calculs avec des polygones, des lignes ou des points tamponnés, les opérateurs spatiaux ne fournissent des résultats exacts que si vous utilisez l'opérateur "relier". Voir l'avertissement en haut de 21.5.6 . Les relations telles que contient, à l'intérieur ou intersectent utilisent le MBR, pas la forme géométrique exacte (c'est-à-dire qu'une ellipse est traitée comme un rectangle).

De plus, les distances dans MySQL Spatial sont dans les mêmes unités que votre première géométrie. Cela signifie que si vous utilisez des degrés décimaux, vos mesures de distance sont en degrés décimaux. Cela rendra très difficile l'obtention de résultats exacts lorsque vous obtiendrez furthur de l'équateur.

James Schek
la source
26
Retrait: MySQL Spatial Extensions ne convient pas pour calculer de grandes distances de cercle entre des points sur la surface de la terre représentés par lat / long. Leurs fonctions de distance, etc., ne sont utiles que sur les coordonnées cartésiennes, planes.
O. Jones
71

Quand j'ai fait cela pour une base de données de navigation construite à partir d'ARINC424, j'ai fait pas mal de tests et en regardant le code, j'ai utilisé un DECIMAL (18,12) (en fait un NUMERIC (18,12) parce que c'était Firebird).

Les flotteurs et les doubles ne sont pas aussi précis et peuvent entraîner des erreurs d'arrondi, ce qui peut être une très mauvaise chose. Je ne me souviens pas si j'ai trouvé de vraies données qui avaient des problèmes - mais je suis assez certain que l'incapacité à stocker avec précision dans un flotteur ou un double pourrait causer des problèmes

Le fait est que lorsque vous utilisez des degrés ou des radians, nous connaissons la plage des valeurs - et la partie fractionnaire a besoin du plus de chiffres.

Les extensions spatiales MySQL sont une bonne alternative car elles suivent le modèle de géométrie OpenGIS . Je ne les ai pas utilisés parce que je devais garder ma base de données portable.

Richard Harrison
la source
3
Merci, cela a été utile. Ça fait bizarre de lire toutes ces questions et réponses de 2008 en réalisant que c'était déjà il y a 8 ans.
aexl
1
@TheSexiestManinJamaica - Avant IEEE 754-1985, le matériel informatique à virgule flottante était chaotique. Il y avait même sur machine où a*bn'était pas égal b*a(pour certaines valeurs). Il y avait de nombreux exemples un peu comme: 2+2 = 3.9999. La norme a nettoyé beaucoup de gâchis et a été «rapidement» adoptée par pratiquement chaque matériel et logiciel. Cette discussion est donc valable, non seulement depuis 2008, mais depuis un tiers de siècle.
Rick James
42

Cela dépend de la précision dont vous avez besoin.

Datatype           Bytes       resolution
------------------ -----  --------------------------------
Deg*100 (SMALLINT)     4  1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
SMALLINT scaled        4   682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6    16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7    16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6   2.7 m    8.8 ft
FLOAT                  8   1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9    16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8    16mm    5/8 in  Marbles
DOUBLE                16   3.5nm     ...    Fleas on a dog

De: http://mysql.rjweb.org/doc.php/latlng

Pour résumer:

  • L'option disponible la plus précise est DOUBLE.
  • Le type vu le plus couramment utilisé est DECIMAL(8,6)/(9,6).

Depuis MySQL 5.7 , envisagez d'utiliser des types de données spatiales (SDT), spécifiquement POINTpour stocker une seule coordonnée. Avant 5.7, SDT ne prend pas en charge les index (à l'exception de 5.6 lorsque le type de table est MyISAM).

Remarque:

  • Lors de l'utilisation de POINTclasse, l'ordre des arguments pour le stockage des coordonnées doit être POINT(latitude, longitude).
  • Il existe une syntaxe spéciale pour créer un index spatial .
  • Le plus grand avantage de l'utilisation de SDT est que vous avez accès aux fonctions d'analyse spatiale , par exemple calculer la distance entre deux points ( ST_Distance) et déterminer si un point est contenu dans une autre zone ( ST_Contains).
Gajus
la source
2
Vous copiez une partie collée d'une réponse précédente et «résumez» avec quelque chose que le gars qui a créé ce tableau n'a pas recommandé : «Comment séparer? Eh bien, MySQL est très difficile. Donc FLOAT / DOUBLE sont sortis. DECIMAL est sorti. Donc, nous sommes coincés avec un peu de kludge. Essentiellement, nous devons convertir Lat / Lng en une certaine taille d'INT et utiliser PARTITION BY RANGE. » ET «FLOAT a 24 bits significatifs; DOUBLE en a 53. (Ils ne fonctionnent pas avec PARTITIONing mais sont inclus pour être complet. Souvent, les gens utilisent DOUBLE sans se rendre compte à quel point c'est exagéré et combien d'espace cela prend.) »Laissez simplement la partie SDT que vous avez écrite.
Armfoot
1
@Armfoot Si vous regardez l'heure des modifications, c'est l'autre réponse qui m'a copié. Ce n'est pas important: je vois Stack Overflow plutôt des "notes pour le futur moi".
Gajus
1
Non, il ne vous a pas copié, il a juste collé le tableau comme vous l'avez fait à partir du lien qu'il a référencé en 2014 (votre message date de 2015). Btw, je pense que vous avez mal orthographié «spécial» lorsque vous avez lié les types de données spatiales . Cette partie que vous avez écrite est en fait utile pour les personnes qui veulent commencer à les utiliser, si vous ajoutez d'autres exemples comme CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;et l'avertissement sur les limitations SDT, comme James l'a mentionné , votre réponse sera peut-être plus concise et précise pour aider les autres. ..
Armfoot
@Gajus - Je suis honoré que vous ayez trouvé mon document à deux! (Non, je ne sais pas à quel point une puce est grosse, mais je sentais qu'elle attirerait l'attention de quelqu'un.)
Rick James
Lors de l'utilisation de la classe POINT, l'ordre des arguments pour le stockage des coordonnées doit être POINT (longitude / X, latitude / Y).
AndreyP
19

À utiliser DECIMAL(8,6)pour la latitude (90 à -90 degrés) et DECIMAL(9,6)pour la longitude (180 à -180 degrés). 6 décimales conviennent à la plupart des applications. Les deux doivent être «signés» pour permettre des valeurs négatives.

Alex Holsgrove
la source
DECIMALLe type est destiné aux calculs financiers où aucun floor/ceiln'est accepté. Plain FLOATsurperforme considérablement DECIMAL.
Kondybas
1
@Kondybas - Étant donné que le coût principal d'une base de données est de récupérer des lignes, la différence de performances entre float et decimal ne devrait pas être un problème.
Rick James
14

Pas besoin d'aller loin, selon Google Maps, le meilleur est FLOAT (10,6) pour lat et lng.

Mariano Peinador
la source
où avez-vous obtenu cette information, je ne la trouve pas? juste au cas où quelque chose changerait.
webfacer
1
@webfacer, c'est dans la section "Création d'une table dans MySQL" ici: developers.google.com/maps/documentation/javascript/… par exemple lat FLOAT( 10, 6 ) NOT NULL, lng FLOAT( 10, 6 ) NOT NULL
turrican_34
1
@webfacer, Il semble que la FLOATsyntaxe soit obsolète depuis mysql 8.0.17. Mysql recommande désormais de simplement utiliser FLOATsans aucun paramètre de précision dev.mysql.com/doc/refman/8.0/en/numeric-type-overview.html et dev.mysql.com/doc/refman/5.5/en/floating-point- types.html
turrican_34
7

Nous stockons la latitude / longitude X 1 000 000 dans notre base de données Oracle sous forme de NOMBRES pour éviter les erreurs d'arrondi avec des doubles.

Étant donné que la latitude / longitude à la 6e décimale était une précision de 10 cm, c'était tout ce dont nous avions besoin. De nombreuses autres bases de données stockent également lat / long à la 6ème décimale.


la source
2
La multiplication par un grand nombre (comme un million) est excellente si vous avez beaucoup de données car les opérations entières (par exemple la récupération indexée) sont beaucoup plus rapides que les flottants.
Kaitlin Duck Sherwood
@KaitlinDuckSherwood - les bits sont des bits - je ne connais aucune raison pour laquelle un flotteur 32 bits serait plus lent à récupérer (indexé ou autre) qu'un entier 32 bits. Même les mathématiques flottantes de nos jours sont assez rapides pour ne pas poser de problème. Néanmoins, je suis d'accord avec le commentaire d'utiliser un multiplicateur implicite avec un entier: il maximise la précision que vous obtenez sur 32 bits. Un peu d'avenir à mesure que la technologie s'améliore.
ToolmakerSteve
6

Dans une perspective complètement différente et plus simple:

  • si vous comptez sur Google pour afficher vos cartes, marqueurs, polygones, peu importe, alors laissez les calculs être effectués par Google!
  • vous enregistrez des ressources sur votre serveur et vous stockez simplement la latitude et la longitude dans une seule chaîne ( VARCHAR), par exemple: " -0000.0000001, -0000.000000000000001 " (35 de longueur et si un nombre a plus de 7 chiffres décimaux, il est arrondi);
  • si Google renvoie plus de 7 chiffres décimaux par numéro, vous pouvez tout de même obtenir ces données stockées dans votre chaîne, au cas où vous souhaiteriez détecter des fuites ou des microbes à l'avenir ;
  • vous pouvez utiliser leur matrice de distance ou leur bibliothèque de géométrie pour calculer des distances ou détecter des points dans certaines zones avec des appels aussi simples que cela:google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
  • il existe de nombreuses API "côté serveur" que vous pouvez utiliser (en Python , Ruby on Rails , PHP , CodeIgniter , Laravel , Yii , Zend Framework , etc.) qui utilisent l'API Google Maps.

De cette façon, vous n'avez pas à vous soucier de l'indexation des nombres et de tous les autres problèmes associés aux types de données qui peuvent gâcher vos coordonnées.

Armfoot
la source
Pas bien. OP a dit qu'il effectuerait des calculs sur les paires lat / lng - vos réponses empêchent cela
Yarin
4
@Yarin C'est une question populaire où quelques (ou beaucoup) de gens ont juste besoin d'une réponse sur la façon de stocker les coordonnées en fonction de leurs propres besoins (beaucoup d'entre eux peuvent simplement utiliser Google maps). Votre downvote suggère que cette réponse ne peut pas les aider ... En stockant les coordonnées dans une chaîne, ils connaîtront exactement les valeurs d'origine qui leur ont été fournies (par exemple: par Google), ce qui les aidera plus tard s'ils décident d'évoluer leur propre application et effectuer des calculs sur eux. À ce moment-là, ils auront toujours les données brutes d'origine simplement parce qu'ils n'ont pas gâché les conversions.
Armfoot
4

selon votre application, je suggère d'utiliser FLOAT (9,6)

les clés spatiales vous donneront plus de fonctionnalités, mais dans les repères de production, les flotteurs sont beaucoup plus rapides que les clés spatiales. (0,01 VS 0,001 en AVG)

Torben Brodt
la source
1
Pouvez-vous fournir ici les détails de votre test?
NameNotFoundException
4

MySQL utilise le double pour tous les flottants ... Utilisez donc le type double. L'utilisation de float entraînera des valeurs arrondies imprévisibles dans la plupart des situations

mlinuxgada
la source
1
MySQL effectue des opérations dansDOUBLE . MySQL vous permet de stocker des données sous forme de 4 octets FLOATou de 8 octets DOUBLE. Il y aura donc probablement une perte de précision lors du stockage d'une expression dans une FLOATcolonne.
Rick James
4

Bien qu'il ne soit pas optimal pour toutes les opérations, si vous créez des tuiles de carte ou travaillez avec un grand nombre de marqueurs (points) avec une seule projection (par exemple, Mercator, comme Google Maps et de nombreux autres cadres de cartes glissantes s'attendent), j'ai trouvé ce que J'appelle "Vast Coordinate System" pour être vraiment, vraiment pratique. Fondamentalement, vous stockez les coordonnées de pixels x et y à un certain zoom - j'utilise le niveau de zoom 23. Cela présente plusieurs avantages:

  • Vous effectuez la transformation coûteuse lat / lng en pixel mercator une fois au lieu de chaque fois que vous gérez le point
  • L'obtention des coordonnées de tuile à partir d'un enregistrement avec un niveau de zoom prend un décalage à droite.
  • L'obtention des coordonnées pixel d'un enregistrement prend un décalage à droite et un ET au niveau du bit.
  • Les décalages sont si légers qu'il est pratique de les faire en SQL, ce qui signifie que vous pouvez faire un DISTINCT pour renvoyer un seul enregistrement par emplacement de pixel, ce qui réduira le nombre d'enregistrements renvoyés par le backend, ce qui signifie moins de traitement sur le l'extrémité avant.

J'ai parlé de tout cela dans un récent article de blog: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/

Kaitlin Duck Sherwood
la source
4

Je suis très surpris par quelques réponses / commentaires.

Pourquoi diable quelqu'un serait-il disposé à "pré-diminuer" volontairement la précision, puis à effectuer plus tard des calculs sur les pires nombres? Cela semble finalement stupide.

Si la source a une précision de 64 bits, il serait certainement stupide de fixer volontairement l'échelle à, par exemple. 6 décimales et limiter la précision à un maximum de 9 chiffres significatifs (ce qui se produit avec le format décimal 9,6 couramment proposé).

Naturellement, on stocke les données avec la précision du matériel source. La seule raison de diminuer la précision serait un espace de stockage limité.

  • Stockez les chiffres source avec une précision originale
  • Stockez les chiffres calculés à partir de la source dans la précision du calcul (par exemple, si le code de réplication utilise des doubles, stockez les résultats sous forme de doubles)

Le format décimal 9,6 provoque un phénomène de snap-to-grid. Cela devrait être la toute dernière étape, si cela devait arriver.

Je n'inviterais pas les erreurs accumulées dans mon nid.

Hurlevent
la source
2
Parce que la plupart des outils et applications GPS ne sont précis qu'à 6 décimales près. Inutile de stocker des données avec une plus grande précision que ce que les outils peuvent mesurer gis.stackexchange.com/questions/8650/…
Yarin
1
@Yarin Oui en effet, mais vous parlez de mesures et de GPS, qui ne sont pas mentionnés dans la question. Il existe certainement des chiffres plus précis. Mais considérons le GPS; disons un ensemble de données source de flottants 64 bits, qui contient déjà une inexactitude. 6 décimales signifie prendre une latitude à environ 11 centimètres. Par conséquent, en stockant uniquement les données (avec 6 décimales) maintenant, vous vous ouvrez à une inexactitude potentielle de 22 cm (si à l'origine 11 cm aussi). Volontairement, probablement pour faire un calcul 64 bits sur cela, avant peut-être de stocker une 3ème fois - maintenant une fenêtre d'imprécision de 33 cm, + -16 cm. Cela semble stupide, à mon humble avis.
Stormwind
@Rick James Je le stockerais probablement en 64 bits, c'est-à-dire. 0.3333333333333333. Nous parlons de géodonnées, non? "1/3" apparaît rarement dans la nature où les choses sont normalement mesurées, avec une précision raisonnable.
Stormwind
4

TL; DR

Utilisez FLOAT (8,5) si vous ne travaillez pas dans la NASA / militaire et ne fabriquez pas de systèmes navi pour avions.


Pour répondre pleinement à votre question, vous devez considérer plusieurs choses:

Format

  • degrés minutes secondes : 40 ° 26 ′ 46 ″ N 79 ° 58 ′ 56 ″ W
  • degrés minutes décimales : 40 ° 26,767 ′ N 79 ° 58,933 ′ O
  • degrés décimaux 1 : 40,446 ° N 79,982 ° W
  • degrés décimaux 2 : -32.60875, 21.27812
  • Un autre format fait maison? Personne ne vous interdit de créer votre propre système de coordonnées centré sur la maison et de le stocker comme cap et distance de votre maison. Cela pourrait avoir un sens pour certains problèmes spécifiques sur lesquels vous travaillez.

La première partie de la réponse serait donc: vous pouvez stocker les coordonnées dans le format utilisé par votre application pour éviter des conversions constantes d'avant en arrière et simplifier les requêtes SQL.

Vous utilisez probablement Google Maps ou OSM pour afficher vos données, et GMaps utilise le format "degrés décimaux 2". Il sera donc plus facile de stocker des coordonnées dans le même format.

Précision

Ensuite, vous souhaitez définir la précision dont vous avez besoin. Bien sûr, vous pouvez stocker des coordonnées comme "-32.608697550570334,21.278081997935146", mais vous êtes-vous déjà soucié des millimètres lors de la navigation jusqu'au point? Si vous ne travaillez pas à la NASA et ne faites pas de trajectoires de satellites ou de fusées ou d'avions, vous devriez être bien avec une précision de plusieurs mètres.

Le format couramment utilisé est de 5 chiffres après les points, ce qui vous donne une précision de 50 cm.

Exemple : il y a une distance de 1 cm entre X, 21.278081 8 et X, 21.278081 9 . Ainsi, 7 chiffres après le point vous donnent une précision de 1/2 cm et 5 chiffres après le point vous donneront une précision de 1/2 mètre (car la distance minimale entre les points distincts est de 1 m, donc l'erreur d'arrondi ne peut pas être supérieure à la moitié). Pour la plupart des fins civiles, cela devrait suffire.

le format des degrés décimaux minutes (40 ° 26,767 ′ N 79 ° 58,933 ′ O) vous donne exactement la même précision que 5 chiffres après le point

Stockage peu encombrant

Si vous avez sélectionné le format décimal, votre coordonnée est une paire (-32.60875, 21.27812). Évidemment, 2 x (1 bit pour le signe, 2 chiffres pour les degrés et 5 chiffres pour l'exposant) suffiront.

Donc, ici, je voudrais soutenir Alix Axel dans les commentaires disant que la suggestion de Google de le stocker dans FLOAT (10,6) est vraiment supplémentaire, car vous n'avez pas besoin de 4 chiffres pour la partie principale (car le signe est séparé et la latitude est limitée à 90 et la longitude est limitée à 180). Vous pouvez facilement utiliser FLOAT (8,5) pour une précision de 1 / 2m ou FLOAT (9,6) pour une précision de 50 / 2cm. Ou vous pouvez même stocker lat et long dans des types séparés, car FLOAT (7,5) est suffisant pour lat. Voir Référence des types de flotteurs MySQL . Chacun d'eux sera comme FLOAT normal et égal à 4 octets de toute façon.

Habituellement, l'espace n'est pas un problème de nos jours, mais si vous voulez vraiment optimiser le stockage pour une raison quelconque (Avertissement: ne faites pas de pré-optimisation), vous pouvez compresser lat (pas plus de 91 000 valeurs + signe) + long (non plus de 181 000 valeurs + signe) à 21 bits, ce qui est nettement inférieur à 2xFLOAT (8 octets == 64 bits)

Le parrain
la source
3

Les fonctions spatiales de PostGIS sont beaucoup plus fonctionnelles (c'est-à-dire non limitées aux opérations BBOX) que celles des fonctions spatiales MySQL. Découvrez-le: texte du lien

Dylan
la source
1
  1. Les latitudes varient de -90 à +90 (degrés), donc DECIMAL (10, 8) est correct pour cela

  2. les longitudes varient de -180 à +180 (degrés), vous avez donc besoin de DECIMAL (11, 8).

Remarque: Le premier nombre est le nombre total de chiffres stockés et le second est le nombre après la virgule décimale.

En bref: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL

mahfuz
la source
0

Je vous suggère d'utiliser le type de données Float pour SQL Server.

Anderson Ribeiro
la source
-2

Les calculs lat longs nécessitent une précision, utilisez donc un type de type décimal et augmentez la précision d'au moins 2 par rapport au nombre que vous stockerez afin d'effectuer des calculs mathématiques. Je ne connais pas les types de données my sql mais dans SQL Server, les gens utilisent souvent float ou real au lieu de decimal et ont des ennuis car ce sont des nombres estimés et non réels. Assurez-vous donc simplement que le type de données que vous utilisez est un vrai type décimal et non un type décimal flottant et que tout devrait bien se passer.

HLGEM
la source
1
les deux types flottants et décimaux ont leur place. en règle générale, les flottants signifient des variables physiques et les décimales sont des entités dénombrables (principalement de l'argent). je ne vois pas pourquoi vous préférez décimal pour lat / long
Javier
1
Je pense aussi que le flotteur est bien pour lat / long. Au moins sur SQL Server (4 octets, 7 chiffres).
Dragoljub Ćurčić
Le flotteur n'est pas exact il est estimé, le lac d'exactitude dans un lat long est fatal! Cela pourrait vous indiquer un endroit complètement différent sur le globe.
HLGEM
2
L'erreur maximale des types de données float est suffisamment faible pour que cela ne soit pas un problème. Je veux dire, vous devez de toute façon être conscient de la multiplication / accumulation d'erreurs avec les deux implémentations.
Spidey
@HLGEM - Arrondir à un certain nombre de décimales vous place également à un endroit différent du globe. La question est de savoir si cet endroit différent est si proche qu'il n'a pas d'importance.
Rick James
-3

A FLOATdevrait vous donner toute la précision dont vous avez besoin et être meilleur pour les fonctions de comparaison que de stocker chaque coordonnée sous forme de chaîne ou similaire.

Si votre version de MySQL est antérieure à 5.0.3, vous devrez peut-être tenir compte de certaines erreurs de comparaison en virgule flottante .

Avant MySQL 5.0.3, les colonnes DECIMAL stockent les valeurs avec une précision exacte car elles sont représentées sous forme de chaînes, mais les calculs sur les valeurs DECIMAL sont effectués à l'aide d'opérations à virgule flottante. Depuis la version 5.0.3, MySQL effectue des opérations DECIMAL avec une précision de 64 chiffres décimaux, ce qui devrait résoudre les problèmes d'imprécision les plus courants en ce qui concerne les colonnes DECIMAL

ConroyP
la source
2
Vous avez besoin d'un véritable type de données de coordonnées latitude / longitude pour un calcul facile. Imaginez la commodité de quelque chose comme l'équivalent de «sélectionner * dans les magasins où la distance (stores.location, mylocation) <5 miles»
Kirk Strauser
1
Je n'avais jamais entendu parler des extensions spatiales auparavant, cela semble très pratique, ayant déjà travaillé sur une application héritée qui effectue pas mal de calculs liés à la géographie, doit la vérifier.
ConroyP
@ConroyP - Non. Cette citation souligne qu'il y DECIMALavait (avant 5.0.3) certaines erreurs dues à l'utilisation de l'implémentation flottante.
Rick James