Qual è il tipo di dati ideale da utilizzare quando si memorizzano latitudine / longitudine in un database MySQL?


432

Tenendo presente che eseguirò calcoli su coppie lat / long, quale tipo di dati è più adatto per l'uso con un database MySQL?


1
Ho trovato questo link molto utile: howto-use-mysql-spatial-ext.blogspot.com/2007/11/… Potrebbe essere un po 'più vecchio, ma contiene una spiegazione completa che include esempi.
madc,

Imho, la maggior parte delle persone qui non capisce cosa succede. Non appena il codice dell'app tocca un numero, purché si utilizzino i doppi (cosa che la maggior parte fa), il numero diventa al massimo doppia precisione . Memorizzarlo quindi con persino un milione di decimali non farà nulla di buono. La sua memorizzazione con un numero limitato di decimali (es. 6) distrugge parte di quella precisione e aggiunge un errore accumulato ogni volta che viene riscritto nel database . Un doppio porta circa 16 numeri significativi, potenzialmente tutti i decimali. Eliminarne 10 crea un errore accumulato nel tempo. È "virgola mobile" per la ragione. Cont.
Stormwind

Cont: 6 decimali possono andare bene quando si memorizza un dato acquisito da una fonte esterna, inalterato e per la prima volta - come materiale sorgente. Ma se si esegue un calcolo su di esso anche una volta e lo si memorizza di nuovo, è stupido rimuovere parte della sua precisione applicando un formato decimale specifico. L'esecuzione del calcolo esclusivamente all'interno del server può essere diversa (il server potrebbe utilizzare o meno qualcos'altro che raddoppia internamente) e l'utilizzo di rappresentazioni numeriche peggiori rispetto al doppio nel calcolo dell'app spesso riduce la necessità di precisione di archiviazione.
Stormwind

Cont: SE il server memorizza il numero con una precisione maggiore , nonostante il preteso "9.6" (che non so se lo fa), allora nulla di tutto ciò che conta e il formato è puramente una questione di convenienza - ha poco da fare con problemi di precisione. Ma non sarei sorpreso se il server arrotonda effettivamente qualsiasi numero in 6 decimali con quel formato.
Stormwind

Cont: Infine: per lat, lon's, il sesto decimale è una questione di scattare in un ca. Griglia di 11 centimetri. Ogni volta che si legge (tocca), si calcola e si memorizza di nuovo, con 6 decimali, si verificherà un nuovo snap (= errore accumulato). Se tutti gli errori succedono nella stessa direzione, si verificherà un grosso errore. Se si eseguono moltiplicazioni temporanee su di esso (ad es. Ingrandimento, sottrazione e riduzione), potrebbe aumentare ancora di più. Non raschiare la precisione senza un buon rason!
Stormwind

Risposte:


161

Usa le estensioni spaziali di MySQL con GIS.


25
Hai altri collegamenti ad esempi o altre informazioni su come iniziare al meglio con loro?
Codebeef

6
MYSQL Spatial è una buona opzione, ma ha ancora limiti e avvertenze significative (a partire da 6). Si prega di vedere la mia risposta qui sotto ...
James Schek,

1
@James Schek ha ragione. Inoltre, MySQL esegue tutti i suoi calcoli utilizzando la geometria euclidea, quindi non rappresenta un caso d'uso reale per lat / lng.
mkuech,

FYI; Mysql supporta l'indice spaziale solo con le tabelle * .myisam, ovvero il motore ISAM. Link: dev.mysql.com/doc/refman/5.0/en/creating-spatial-indexes.html
PodTech.io


150

Google fornisce un inizio per completare la soluzione PHP / MySQL per un'applicazione "Store Locator" di esempio con Google Maps. In questo esempio, memorizzano i valori lat / lng come "Float" con una lunghezza di "10,6"

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


11
Google chiaramente non capisce come funziona la specifica FLOAT: FLOAT(10,6)lascia 4 cifre per la parte intera della coordinata. E no, il segno non conta - viene dall'attributo (non) firmato.
Alix Axel,

2
Ma se è necessario memorizzare come valori di parti integrali da [0, 180] dovrebbe essere più che sufficiente, giusto?
Hrvoje Golcic,

37
@AlixAxel Penso che Google sappia cosa sta facendo. Perché afferma che: " Con le attuali funzionalità di zoom di Google Maps, dovresti avere solo 6 cifre di precisione dopo il decimale. Ciò consentirà ai campi di memorizzare 6 cifre dopo il decimale, più fino a 4 cifre prima del decimale, ad es. - 123.456789 gradi. ". Se è selezionato unsigned, il modello sarà 1234.567890 . Quindi nessun problema.
1.44mb del

16
@AlixAxel Sta contando i numeri nella sequenza; non usando una coordinata reale ...
Andrew Ellis,

8
Utilizzo del tipo Doubledi dati per Laravel
FooBar

134

Fondamentalmente dipende dalla precisione di cui hai bisogno per le tue posizioni. Usando DOUBLE avrai una precisione di 3,5 nm. DECIMAL (8,6) / (9,6) scende a 16 cm. GALLEGGIANTE è 1,7 m ...

Questa tabella molto interessante ha un elenco più completo: 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

Spero che sia di aiuto.


2
Devo scrivere un commento costruttivo e dettagliato incentrato sul contenuto dei post, quindi dirò che mentre osservavo la tabella di accuratezza fornita dal sito Web di Rick James, ero leggermente divertito dalla descrizione della risoluzione "pulci su un cane" e lo sentivo degno di complimenti. Tecnicamente parlando, questa è stata una rappresentazione utile che mi ha aiutato a decidere quale tipo di dati usare quando si memorizzano le coordinate per misurare la distanza tra due indirizzi, che, @Simon, vorrei ringraziarvi per la condivisione.
Sam_Butler,

FWIW, l'uso di quel link di "SMALLINT ridimensionato" è terribilmente inefficiente. La risposta di Oguzhan è un ottimo modo per memorizzare long / lat con 7 cifre dopo il punto decimale, in un int con segno a 4 byte. Grande precisione (~ 1 cm) in dimensioni ridotte (4B).
ToolmakerSteve

74

Le estensioni spaziali di MySQL sono l'opzione migliore perché hai l'elenco completo di operatori e indici spaziali a tua disposizione. Un indice spaziale ti consentirà di eseguire calcoli basati sulla distanza molto rapidamente. Tieni presente che a partire dalla 6.0, l'estensione spaziale è ancora incompleta. Non sto abbattendo MySQL Spatial, solo per farti conoscere le insidie ​​prima di andare troppo avanti su questo.

Se hai a che fare con i punti e solo con la funzione DISTANZA, va bene. Se è necessario eseguire calcoli con poligoni, linee o punti bufferizzati, gli operatori spaziali non forniscono risultati esatti a meno che non si utilizzi l'operatore "correlazione". Vedere l'avvertenza nella parte superiore di 21.5.6 . Le relazioni come contiene, all'interno o intersecano utilizzano l'MBR, non la forma geometrica esatta (ovvero un'ellisse viene trattata come un rettangolo).

Inoltre, le distanze in MySQL Spatial sono nelle stesse unità della tua prima geometria. Ciò significa che se si utilizzano i gradi decimali, le misurazioni della distanza sono in gradi decimali. Ciò renderà molto difficile ottenere risultati esatti quando si ottiene furthur dall'equatore.


26
Restating: le estensioni spaziali MySQL non sono adatte per calcolare grandi distanze circolari tra i punti sulla superficie della terra rappresentata da lat / long. Le loro funzioni di distanza, ecc., Sono utili solo su cartesiane, planari, coordinate.
O. Jones,

71

Quando l'ho fatto per un database di navigazione creato da ARINC424, ho fatto un bel po 'di test e guardando indietro al codice, ho usato un DECIMAL (18,12) (in realtà un NUMERIC (18,12) perché era firebird).

Galleggianti e doppi non sono così precisi e possono causare errori di arrotondamento che possono essere una cosa molto negativa. Non riesco a ricordare se ho trovato dati reali che avevano problemi - ma sono abbastanza certo che l'incapacità di archiviare accuratamente in un float o in un doppio potrebbe causare problemi

Il punto è che quando si usano gradi o radianti conosciamo l'intervallo dei valori e la parte frazionata ha bisogno del maggior numero di cifre.

Le estensioni spaziali MySQL sono una buona alternativa perché seguono il modello geometria OpenGIS . Non li ho usati perché dovevo mantenere il mio database portatile.


3
Grazie, questo è stato utile. Sembra strano leggere tutte queste domande e risposte dal 2008 rendendosi conto che era già 8 anni fa.
aexl

1
@TheSexiestManinJamaica - Prima dell'IEEE 754-1985, l'hardware a virgola mobile del computer era caotico. C'era anche sulla macchina dove a*bnon era uguale b*a(per alcuni valori). Ci sono stati molti esempi un po 'come: 2+2 = 3.9999. Lo standard ha ripulito un sacco di confusione ed è stato "rapidamente" adottato praticamente da ogni componente hardware e software. Quindi, questa discussione è stata valida, non solo dal 2008, ma per un terzo di secolo.
Rick James,

42

Dipende dalla precisione richiesta.

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

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

Riassumere:

  • L'opzione disponibile più precisa è DOUBLE.
  • Il tipo visto più comunemente usato è DECIMAL(8,6)/(9,6).

A partire da MySQL 5.7 , considera l'utilizzo di Tipi di dati spaziali (SDT), in particolare POINTper la memorizzazione di una singola coordinata. Prima di 5.7, SDT non supporta gli indici (ad eccezione di 5.6 quando il tipo di tabella è MyISAM).

Nota:

  • Quando si utilizza la POINTclasse, l'ordine degli argomenti per la memorizzazione delle coordinate deve essere POINT(latitude, longitude).
  • Esiste una sintassi speciale per la creazione di un indice spaziale .
  • Il principale vantaggio dell'utilizzo di SDT è che si ha accesso alle funzioni di analisi spaziale , ad esempio il calcolo della distanza tra due punti ( ST_Distance) e la determinazione se un punto è contenuto in un'altra area ( ST_Contains).

2
Copi la parte incollata di una risposta precedente e "riassumi" con qualcosa che il ragazzo che ha creato quella tabella non ha raccomandato : «Come si partiziona? Bene, MySQL è molto esigente. Quindi FLOAT / DOUBLE sono fuori. DECIMAL è fuori. Quindi, siamo bloccati con un po 'di clamore. In sostanza, dobbiamo convertire Lat / Lng in una dimensione di INT e utilizzare PARTITION BY RANGE. » E «FLOAT ha 24 bit significativi; DOUBLE ha 53. (Non funzionano con PARTITIONing ma sono inclusi per completezza. Spesso le persone usano DOUBLE senza rendersi conto di quanto sia eccessivo e di quanto spazio occupi.) »Lascia semplicemente la parte SDT che hai scritto.
Armfoot,

1
@Armfoot Se guardi l'ora delle modifiche, è l'altra risposta che mi ha copiato. Non importa: sto vedendo Stack Overflow più di un "note per il futuro me".
Gajus,

1
No, non ti ha copiato, ha appena incollato il tavolo come hai fatto dal link a cui ha fatto riferimento nel 2014 (il tuo post è del 2015). A proposito, penso che tu abbia scritto male "Speciale" quando hai collegato i tipi di dati spaziali . Questa parte che hai scritto è in realtà utile per le persone che vogliono iniziare a usarle, se aggiungi altri esempi come CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;e l'avvertimento sulle limitazioni SDT, come ha detto James , forse la tua risposta sarà più concisa e precisa nell'aiutare anche altre persone. ..
Armfoot,

@ Gajus - Sono onorato che due di voi abbiano trovato il mio documento! (No, non so quanto sia grande una pulce, ma ho sentito che avrebbe attirato l'attenzione di qualcuno.)
Rick James,

Quando si utilizza la classe POINT, l'ordine degli argomenti per la memorizzazione delle coordinate deve essere POINT (longitudine / X, latitudine / Y).
AndreyP


19

Utilizzare DECIMAL(8,6)per latitudine (da 90 a -90 gradi) e DECIMAL(9,6)per longitudine (da 180 a -180 gradi). 6 decimali vanno bene per la maggior parte delle applicazioni. Entrambi dovrebbero essere "firmati" per consentire valori negativi.


DECIMALtipo è inteso per calcoli finanziari in cui non floor/ceilè accettato. Plain FLOATsupera significativamente le prestazioni DECIMAL.
Kondybas,

1
@Kondybas - Poiché il costo principale in un database è il recupero delle righe, la differenza di prestazioni tra float e decimale non dovrebbe essere un problema.
Rick James,

14

Non c'è bisogno di andare lontano, secondo Google Maps, il migliore è FLOAT (10,6) per lat e lng.


dove hai preso queste informazioni non le trovo? nel caso in cui qualcosa cambi.
webfacer,

1
@webfacer, è nella sezione "Creazione di una tabella in MySQL" qui: developers.google.com/maps/documentation/javascript/… es. lat FLOAT( 10, 6 ) NOT NULL, lng FLOAT( 10, 6 ) NOT NULL
turrican_34,

1
@webfacer, sembra che la FLOATsintassi sia obsoleta a partire da mysql 8.0.17. Mysql ora consiglia di utilizzare FLOATsenza parametri di precisione dev.mysql.com/doc/refman/8.0/en/numeric-type-overview.html e dev.mysql.com/doc/refman/5.5/en/floating-point- types.html
turrican_34,

7

Memorizziamo latitudine / longitudine X 1.000.000 nel nostro database Oracle come NUMERI per evitare errori di arrotondamento con i doppi.

Dato che latitudine / longitudine al 6 ° decimale era una precisione di 10 cm che era tutto ciò di cui avevamo bisogno. Molti altri database memorizzano anche lat / long al sesto decimale.


2
Moltiplicare per un numero elevato (come un milione) è ottimo se si dispone di molti dati poiché le operazioni di numero intero (ad esempio il recupero indicizzato) sono molto più veloci dei float.
Kaitlin Duck Sherwood,

@KaitlinDuckSherwood - i bit sono bit - Non sono a conoscenza di alcun motivo per cui un float a 32 bit sarebbe più lento per il recupero (indicizzato o meno) di un numero intero a 32 bit. Anche la matematica fluttuante in questi giorni è abbastanza veloce per essere un problema. Tuttavia, sono d'accordo con il commento di utilizzare il moltiplicatore implicito con un numero intero: massimizza la precisione che ottieni da 32 bit. Un po 'a prova di futuro con il miglioramento della tecnologia.
ToolmakerSteve

6

In una prospettiva completamente diversa e più semplice:

  • se fai affidamento su Google per mostrare mappe, marcatori, poligoni o altro, lascia che i calcoli vengano eseguiti da Google!
  • risparmi risorse sul tuo server e memorizzi insieme latitudine e longitudine come un'unica stringa ( VARCHAR), ad esempio: " -0000.0000001, -0000.000000000000001 " (lunghezza 35 e se un numero ha più di 7 cifre decimali, viene arrotondato);
  • se Google restituisce più di 7 cifre decimali per numero, puoi comunque ottenere quei dati memorizzati nella tua stringa, nel caso in cui desideri rilevare alcuni fuggitivi o microbi in futuro ;
  • puoi usare la loro matrice di distanza o la loro libreria di geometrie per calcolare le distanze o rilevare punti in determinate aree con chiamate semplici come questa:google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
  • ci sono molte API "lato server" che puoi usare (in Python , Ruby on Rails , PHP , CodeIgniter , Laravel , Yii , Zend Framework , ecc.) che utilizzano l'API di Google Maps.

In questo modo non devi preoccuparti di indicizzare i numeri e tutti gli altri problemi associati ai tipi di dati che potrebbero rovinare le tue coordinate.


Non buono. OP ha detto che avrebbe eseguito calcoli sulle coppie lat / lng - le tue risposte lo precludono
Yarin

4
@Yarin Questa è una domanda popolare in cui poche (o molte) persone hanno solo bisogno di una risposta su come memorizzare le coordinate in base alle proprie esigenze (molti di loro possono semplicemente utilizzare le mappe di Google). Il tuo downvote suggerisce che questa risposta potrebbe non aiutarli ... Memorizzando le coordinate in una stringa conosceranno esattamente i valori originali che sono stati forniti loro (ad esempio: da Google) che li aiuteranno in seguito se decidono di evolvere il loro propria app ed eseguire calcoli su di essi. A quel tempo, avranno ancora i dati grezzi originali solo perché non li hanno confusi con le conversioni.
Armfoot,

4

a seconda dell'applicazione, suggerisco di utilizzare FLOAT (9,6)

le chiavi spaziali ti daranno più funzionalità, ma nei benchmark di produzione i float sono molto più veloci delle chiavi spaziali. (0,01 VS 0,001 in AVG)


1
Potete per favore fornire i risultati del test con i dettagli qui?
NameNotFoundException il

4

MySQL usa il doppio per tutti i float ... Quindi usa il tipo double. L'uso di float porterà a valori arrotondati imprevedibili nella maggior parte delle situazioni


1
MySQL esegue operazioni inDOUBLE . MySQL ti consente di archiviare i dati come 4 byte FLOATo 8 byte DOUBLE. Pertanto, è probabile che si verifichi una perdita di precisione durante la memorizzazione di un'espressione in una FLOATcolonna.
Rick James,

4

Sebbene non sia ottimale per tutte le operazioni, se stai realizzando riquadri di mappe o lavorando con un gran numero di marcatori (punti) con una sola proiezione (ad esempio Mercator, come Google Maps e molti altri framework di mappe scivolose si aspettano), ho trovato quello che Chiamo "Vast Coordinate System" per essere davvero molto utile. Fondamentalmente, memorizzi le coordinate dei pixel xey in un modo ingrandito - Uso il livello di zoom 23. Questo ha diversi vantaggi:

  • Effettui la costosa trasformazione da lat / lng a mercator pixel una volta anziché ogni volta che gestisci il punto
  • Ottenere le coordinate della piastrella da un record dato un livello di zoom richiede uno spostamento a destra.
  • Ottenere la coordinata dei pixel da un record richiede uno spostamento a destra e uno AND bit a bit.
  • I turni sono così leggeri che è pratico eseguirli in SQL, il che significa che puoi fare un DISTINCT per restituire solo un record per posizione dei pixel, il che ridurrà i record numerici restituiti dal backend, il che significa meno elaborazione sul fine frontale.

Ne ho parlato in un recente post sul blog: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/


4

Sono molto sorpreso da alcune risposte / commenti.

Perché mai qualcuno dovrebbe essere disposto a "pre-diminuire" volontariamente la precisione, e in seguito eseguire calcoli sui numeri peggiori? Alla fine sembra stupido.

Se la sorgente ha una precisione a 64 bit, certamente sarebbe stupido fissare volontariamente la scala ad es. 6 decimali e limita la precisione a un massimo di 9 cifre significative (cosa che accade con il formato decimale 9.6 comunemente proposto).

Naturalmente, si memorizzano i dati con la precisione del materiale di origine. L'unico motivo per ridurre la precisione sarebbe lo spazio di archiviazione limitato.

  • Memorizza i dati sorgente con precisione originale
  • Memorizza le cifre calcolate dalla sorgente con precisione nel calcolo (ad es. Se il codice di applicazione utilizza doppie, archivia i risultati come doppie)

Il formato decimale 9.6 genera un fenomeno snap-to-grid. Questo dovrebbe essere l'ultimo passo, se mai dovesse succedere.

Non inviterei errori accumulati nel mio nido.


2
Perché la maggior parte degli strumenti e delle applicazioni GPS sono precisi solo con 6 decimali. Inutile archiviare i dati con una precisione maggiore rispetto a quali strumenti possono misurare gis.stackexchange.com/questions/8650/…
Yarin

1
Sì, sì, ma parli di misure e GPS, che non sono menzionati nella domanda. Sicuramente esistono cifre più precise. Ma consideriamo il GPS; ad esempio un set di dati di origine di float a 64 bit, che contiene già un'imprecisione. 6 decimali significa scattare una latitudine al più vicino ca 11 centimetri. Quindi, memorizzando solo i dati (con 6 decimali) ora, si apre una potenziale imprecisione di 22 cm (se originariamente anche 11 cm). Volontariamente, probabilmente per fare un calcolo a 64 bit su quello, prima forse di memorizzare una terza volta - ora finestra di imprecisione di 33 cm, + -16 cm. Sembra stupido, imho.
Stormwind,

@Rick James Probabilmente lo memorizzerei come 64-bit, cioè. ,3333333333333333. Parliamo di geodati, giusto? "1/3" appare raramente in natura dove le cose vengono normalmente misurate, con una ragionevole precisione.
Stormwind

4

TL; DR

Usa FLOAT (8,5) se non lavori nella NASA / militare e non stai realizzando sistemi di navi per aeromobili.


Per rispondere pienamente alla tua domanda, dovresti considerare diverse cose:

Formato

  • gradi minuti secondi : 40 ° 26 ′ 46 ″ N 79 ° 58 ′ 56 ″ O
  • gradi minuti decimali : 40 ° 26,767 ′ N 79 ° 58,933 ′ O
  • gradi decimali 1 : 40,446 ° N 79,982 ° O
  • gradi decimali 2 : -32.60875, 21.27812
  • Qualche altro formato fatto in casa? Nessuno ti proibisce di creare il tuo sistema di coordinate centrato sulla tua casa e di memorizzarlo come direzione e distanza da casa tua. Questo potrebbe avere senso per alcuni problemi specifici su cui stai lavorando.

Quindi la prima parte della risposta sarebbe: è possibile memorizzare le coordinate nel formato utilizzato dall'applicazione per evitare conversioni costanti avanti e indietro e rendere più semplici le query SQL.

Molto probabilmente usi Google Maps o OSM per visualizzare i tuoi dati e GMaps utilizza il formato "gradi decimali 2". Quindi sarà più facile memorizzare le coordinate nello stesso formato.

Precisione

Quindi, desideri definire la precisione di cui hai bisogno. Ovviamente puoi memorizzare coordinate come "-32.608697550570334,21.278081997935146", ma ti sei mai preoccupato dei millimetri durante la navigazione verso il punto? Se non stai lavorando nella NASA e non stai realizzando satelliti o missili o traiettorie di aerei, dovresti andare bene con diversi metri di precisione.

Il formato comunemente usato è di 5 cifre dopo i punti, per una precisione di 50 cm.

Esempio : c'è una distanza di 1 cm tra X, 21.278081 8 e X, 21.278081 9 . Quindi 7 cifre dopo punto offrono una precisione di 1/2 cm e 5 cifre dopo punto offrono una precisione di 1/2 metri (poiché la distanza minima tra punti distinti è 1m, quindi l'errore di arrotondamento non può essere superiore alla metà). Per la maggior parte degli scopi civili dovrebbe essere sufficiente.

gradi formato minuti decimali (40 ° 26.767 ′ N 79 ° 58.933 ′ O) offre esattamente la stessa precisione di 5 cifre dopo il punto

Archiviazione efficiente in termini di spazio

Se hai selezionato il formato decimale, le tue coordinate sono una coppia (-32.60875, 21.27812). Ovviamente, saranno sufficienti 2 x (1 bit per segno, 2 cifre per gradi e 5 cifre per esponente).

Quindi qui vorrei supportare Alix Axel dai commenti dicendo che il suggerimento di Google di memorizzarlo in FLOAT (10,6) è davvero extra, perché non hai bisogno di 4 cifre per la parte principale (poiché il segno è separato e la latitudine è limitata a 90 e la longitudine è limitata a 180). Puoi facilmente usare FLOAT (8,5) per una precisione di 1/2 m o FLOAT (9,6) per una precisione di 50/2 cm. Oppure puoi anche memorizzare lat e long in tipi separati, perché FLOAT (7,5) è sufficiente per lat. Vedi riferimento ai tipi di float MySQL . Ognuno di loro sarà come un normale FLOAT e comunque uguale a 4 byte.

Di solito lo spazio non è un problema al giorno d'oggi, ma se vuoi davvero ottimizzare l'archiviazione per qualche motivo (Dichiarazione di non responsabilità: non eseguire la pre-ottimizzazione), puoi comprimere lat (non più di 91000 valori + segno) + long (no più di 181000 valori + segno) a 21 bit che è significativamente inferiore a 2xFLOAT (8 byte == 64 bit)


3

Le funzioni spaziali in PostGIS sono molto più funzionali (cioè non vincolate alle operazioni BBOX) rispetto a quelle nelle funzioni spaziali MySQL. Dai un'occhiata: link del testo


1
  1. Le latitudini vanno da -90 a +90 (gradi), quindi DECIMAL (10, 8) va bene per quello

  2. le lunghezze vanno da -180 a +180 (gradi) quindi è necessario DECIMAL (11, 8).

Nota: il primo numero è il numero totale di cifre memorizzate e il secondo è il numero dopo il punto decimale.

In breve: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL



-2

I calcoli Lat Long richiedono precisione, quindi usa un tipo di decimale e aumenta la precisione di almeno 2 in più rispetto al numero che memorizzerai per eseguire calcoli matematici. Non conosco i miei tipi di dati sql, ma in SQL Server le persone usano spesso float o real invece di decimali e si mettono nei guai perché si tratta di numeri stimati non reali. Quindi assicurati solo che il tipo di dati che usi sia un tipo decimale vero e non un tipo decimale mobile e dovresti andare bene.


1
entrambi i tipi float e decimali hanno il loro posto. come regola generale, i float significano variabili fisiche e i decimali sono per entità numerabili (principalmente denaro). non vedo perché preferiresti il ​​decimale per lat / long
Javier

1
Penso anche che float vada bene per lat / long. Almeno su SQL Server (4 byte, 7 cifre).
Dragoljub Ćurčić,

Il galleggiante non è esatto è stimato, il lago di esattezza in un lat long è fatale! Potrebbe indicarti un punto completamente diverso sul globo.
HLGEM,

2
L'errore massimo dei tipi di dati float è abbastanza basso da non costituire un problema. Voglio dire, devi essere consapevole della moltiplicazione / accumulo di errori con entrambe le implementazioni comunque.
Spidey,

@HLGEM - L'arrotondamento ad un certo numero di cifre decimali ti porta anche in un punto diverso del globo. La domanda è se quel punto diverso è così vicino che non importa.
Rick James,

-3

A FLOATdovrebbe darti tutta la precisione di cui hai bisogno ed essere migliore per le funzioni di confronto rispetto alla memorizzazione di ciascuna coordinata come stringa o simili.

Se la tua versione di MySQL è precedente alla 5.0.3, potresti dover tenere conto di alcuni errori di confronto in virgola mobile .

Prima di MySQL 5.0.3, le colonne DECIMAL memorizzano i valori con precisione esatta perché sono rappresentate come stringhe, ma i calcoli sui valori DECIMAL vengono eseguiti utilizzando operazioni in virgola mobile. A partire dalla 5.0.3, MySQL esegue operazioni DECIMAL con una precisione di 64 cifre decimali, che dovrebbe risolvere i problemi di imprecisione più comuni quando si tratta di colonne DECIMAL


2
È necessario un vero tipo di dati delle coordinate di latitudine / longitudine per facilitare la matematica. Immagina la convenienza di qualcosa come l'equivalente di "seleziona * dai negozi in cui distanza (negozi.locazione, collocazione) <5 miglia"
Kirk Strauser

1
Non avevo mai sentito parlare delle estensioni spaziali prima, suona molto bene, avendo precedentemente lavorato su un'app ereditata che fa un bel po 'di calcoli geo-correlati, deve verificarlo.
ConroyP

@ConroyP - No. Quella citazione sta sottolineando che DECIMAL(prima della 5.0.3) c'erano alcuni errori dovuti all'uso dell'implementazione mobile.
Rick James,
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.