Qual é o tipo de dados ideal para usar ao armazenar latitude / longitude em um banco de dados MySQL?


432

Tendo em mente que executarei cálculos em pares lat / long, que tipo de dados é mais adequado para uso com um banco de dados MySQL?


1
Achei este link muito útil: howto-use-mysql-spatial-ext.blogspot.com/2007/11/… Pode ser um pouco mais antigo, mas contém uma explicação completa, incluindo exemplos.
madc 15/07/11

A maioria das pessoas aqui não entende o que acontece. Assim que o código do aplicativo toca em um número, desde que se use o dobro (o que a maioria faz), o número se transforma em uma precisão dupla . Armazená-lo com um milhão de casas decimais não é bom. Armazená-lo com um número limitado de casas decimais (por exemplo, 6) destrói parte dessa precisão e adiciona um erro acumulado cada vez que é reescrito no banco de dados . Um duplo carrega cerca de 16 números significativos, potencialmente todos os decimais. Eliminar 10 deles cria um erro acumulado ao longo do tempo. É "ponto flutuante" pela razão. Cont.
Stormwind

Cont: 6 casas decimais podem ser aceitáveis ​​ao armazenar uma figura adquirida de uma fonte externa, inalterada e pela primeira vez - como material de origem. Porém, se você realizar um cálculo nele mesmo uma vez e armazená-lo novamente, é estúpido remover parte de sua precisão aplicando um formato decimal específico. A execução do cálculo apenas dentro do servidor pode ser diferente (o servidor pode ou não estar usando algo além de duplicar internamente) e usar representações numéricas piores do que o dobro no cálculo do aplicativo ofc diminui igualmente a necessidade de precisão de armazenamento.
Stormwind

Cont: SE o servidor armazena o número com uma precisão mais alta , apesar dos "9.6" alegados (que eu não sei se existe), nada disso importa e o formato é apenas uma questão de conveniência - tem pouco a ver fazer com problemas de precisão. Mas eu não ficaria surpreso se o servidor realmente arredondar qualquer número para uma precisão decimal de 6 com esse formato.
Stormwind

Cont: Finalmente: para lat, lon, o sexto decimal é uma questão de encaixar em um ca. Grade de 11 centímetros. Cada vez que se lê (toca), calcula e armazena novamente, com 6 casas decimais, haverá um novo snap (= erro acumulado). Se todos os erros forem na mesma direção, haverá um grande erro. Se realizar multiplicações temporárias nele (por exemplo, aumentar, subtrair e diminuir), ele poderá aumentar ainda mais. Não descarte a precisão sem um bom rason!
Stormwind

Respostas:


161

Use as extensões espaciais do MySQL com GIS.


25
Você tem outros links para exemplos ou outras informações sobre como começar com eles?
Codebeef 01/10/08

6
O MYSQL Spatial é uma boa opção, mas ainda possui limites e advertências significativas (a partir de 6). Por favor, veja minha resposta abaixo ...
James Schek 2/08/08

1
@ James Schek está certo. Além disso, o MySQL faz todos os seus cálculos usando geometria euclidiana, portanto não representa um caso de uso no mundo real para lat / lng.
mkuech

PARA SUA INFORMAÇÃO; O Mysql suporta índice espacial apenas com tabelas * .myisam, ou seja, o mecanismo ISAM. Link: dev.mysql.com/doc/refman/5.0/en/creating-spatial-indexes.html
PodTech.io

Ter um olhar para este artigo na parte Atualização final: mysqlserverteam.com/mysql-5-7-and-gis-an-example
Jaspal Singh

150

O Google fornece uma solução PHP / MySQL do início ao fim para um exemplo de aplicativo "Localizador de lojas" no Google Maps. Neste exemplo, eles armazenam os valores de lat / lng como "Float" com um comprimento de "10,6"

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


11
O Google claramente não entende como a especificação FLOAT funciona: FLOAT(10,6)deixa 4 dígitos para a parte inteira da coordenada. E não, o sinal não conta - isso vem do atributo (des) assinado.
Alix Axel

2
Mas se você precisar armazenar como valores integrais de peças de [0, 180], deve ser mais do que suficiente, certo?
Hrvoje Golcic

37
@AlixAxel Acho que o Google sabe o que está fazendo. Porque afirma que: " Com os recursos atuais de zoom do Google Maps, você só precisa de 6 dígitos de precisão após o decimal. Isso permitirá que os campos armazenem 6 dígitos após o decimal, além de até 4 dígitos antes do decimal, por exemplo - 123,456789 graus ". Se não assinado estiver marcado, o padrão será 1234,567890 . Portanto, sem problemas.
1.44mb

16
@AlixAxel Ele está contando os números na sequência; não usando uma coordenada real ...
Andrew Ellis

8
Usando o tipo Doublede dados para o Laravel
FooBar 11/11

134

Basicamente, depende da precisão que você precisa para seus locais. Usando DOUBLE, você terá uma precisão de 3,5 nm. DECIMAL (8,6) / (9,6) desce para 16 cm. FLOAT é de 1,7 m ...

Esta tabela muito interessante possui uma lista mais completa: 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

Espero que isto ajude.


2
Preciso escrever um comentário construtivo e detalhado, focado no conteúdo das postagens, por isso direi que, enquanto observava a tabela de precisão conforme fornecida no site de Rick James, fiquei levemente divertida com a descrição da resolução "pulgas em um cachorro" e senti digno de elogios. Tecnicamente falando, essa foi uma representação útil que me ajudou a decidir que tipo de dados usar ao armazenar coordenadas para medir a distância entre dois endereços, os quais, @Simon, gostaria de agradecer por compartilhar.
Sam_Butler

FWIW, o uso desse link de "SMALLINT redimensionado" é terrivelmente ineficiente. A resposta de Oguzhan é uma ótima maneira de armazenar long / lat com 7 dígitos após o ponto decimal, em um int assinado de 4 bytes. Grande precisão (~ 1 cm) em tamanho pequeno (4B).
ToolmakerSteve

74

As extensões espaciais do MySQL são a melhor opção porque você tem a lista completa de operadores e índices espaciais à sua disposição. Um índice espacial permitirá realizar cálculos baseados em distância muito rapidamente. Lembre-se de que, a partir da versão 6.0, a extensão espacial ainda está incompleta. Não estou descartando o MySQL Spatial, apenas informando sobre as armadilhas antes que você se demore demais nisso.

Se você estiver lidando estritamente com pontos e apenas com a função DISTANCE, tudo bem. Se você precisar fazer cálculos com polígonos, linhas ou pontos de buffer, os operadores espaciais não fornecerão resultados exatos, a menos que você use o operador "relacionar". Veja o aviso na parte superior de 21.5.6 . Relacionamentos como contém, dentro ou interseções estão usando o MBR, não a forma exata da geometria (ou seja, um Ellipse é tratado como um retângulo).

Além disso, as distâncias no MySQL Spatial estão nas mesmas unidades que sua primeira geometria. Isso significa que, se você estiver usando graus decimais, suas medidas de distância serão em graus decimais. Isso tornará muito difícil obter resultados exatos à medida que você se aproxima do equador.


26
Atualização: As extensões espaciais do MySQL não são adequadas para calcular grandes distâncias de círculo entre pontos na superfície da Terra representados por lat / long. Suas funções de distância etc. são úteis apenas em coordenadas cartesianas, planas.
O. Jones

71

Quando fiz isso para um banco de dados de navegação construído a partir do ARINC424, fiz uma boa quantidade de testes e, olhando para o código, usei um DECIMAL (18,12) (atualmente um NUMERIC (18,12) porque era o firebird).

Flutuadores e duplos não são tão precisos e podem resultar em erros de arredondamento, o que pode ser uma coisa muito ruim. Não me lembro se encontrei dados reais com problemas - mas tenho certeza de que a incapacidade de armazenar com precisão em um float ou double pode causar problemas

O ponto é que, ao usar graus ou radianos, sabemos a faixa dos valores - e a parte fracionária precisa de mais dígitos.

As extensões espaciais do MySQL são uma boa alternativa, porque seguem o OpenGIS Geometry Model . Não os usei porque precisava manter meu banco de dados portátil.


3
Obrigado, isso foi útil. É estranho ler todas essas perguntas e respostas de 2008 ao perceber que isso já acontecia há 8 anos.
aexl

1
@TheSexiestManinJamaica - Antes da IEEE 754-1985, o hardware de ponto flutuante do computador era caótico. Havia até na máquina onde a*bnão era igual b*a(para alguns valores). Houve muitos exemplos um pouco como: 2+2 = 3.9999. O padrão limpava muita bagunça e era "rapidamente" adotado por praticamente todas as peças de hardware e software. Portanto, essa discussão é válida, não apenas desde 2008, mas por um terço de século.
Rick James

42

Depende da precisão que você precisa.

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

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

Para resumir:

  • A opção mais precisa disponível é DOUBLE.
  • O tipo visto mais comum usado é DECIMAL(8,6)/(9,6).

No MySQL 5.7 , considere o uso de Tipos de Dados Espaciais (SDT), especificamente POINTpara armazenar uma única coordenada. Antes do 5.7, o SDT não suporta índices (com exceção de 5.6 quando o tipo de tabela é MyISAM).

Nota:

  • Ao usar a POINTclasse, a ordem dos argumentos para armazenar coordenadas deve ser POINT(latitude, longitude).
  • Há uma sintaxe especial para criar um índice espacial .
  • O maior benefício do uso do SDT é que você tem acesso às Funções de Análise Espacial , por exemplo, calculando a distância entre dois pontos ( ST_Distance) e determinando se um ponto está contido em outra área ( ST_Contains).

2
Você copiou parte colada de uma resposta anterior e "resumiu" com algo que o cara que criou essa tabela não recomendou : «Como PARTIR? Bem, o MySQL é muito exigente. Então, FLOAT / DOUBLE está fora. DECIMAL está fora. Então, nós estamos presos com alguns elogios. Essencialmente, precisamos converter Lat / Lng para algum tamanho da INT e usar PARTITION BY RANGE. » AND «FLOAT possui 24 bits significativos; O DOUBLE tem 53. (Eles não funcionam com PARTITIONing, mas são incluídos para fins completos. Geralmente, as pessoas usam o DOUBLE sem perceber quanto é um exagero e quanto espaço é necessário.) »Deixe a parte SDT que você escreveu.
Armfoot

1
@Armfoot Se você olhar a hora das edições, é a outra resposta que me foi copiada. Não que isso importe: estou vendo o Stack Overflow mais como "notas para o futuro".
Gajus 26/11/2015

1
Não, ele não copiou de você, ele apenas colou a tabela como você fez no link que ele referenciou em 2014 (sua postagem é de 2015). Aliás, acho que você digitou incorretamente "Especial" ao vincular Tipos de Dados Espaciais . Esta parte que você escreveu é realmente útil para pessoas que desejam começar a usá-las. Se você adicionar mais alguns exemplos, como CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;o aviso sobre as limitações do SDT, como James mencionou , talvez sua resposta seja mais concisa e precisa para ajudar outras pessoas também. ..
Armfoot

@ Gajus - Estou honrado que vocês dois encontraram meu documento! (Não, eu não sei o quão grande uma pulga é, mas eu senti que iria chamar a atenção de alguém.)
Rick James

Ao usar a classe POINT, a ordem dos argumentos para armazenar coordenadas deve ser POINT (longitude / X, latitude / Y).
AndreyP


19

Use DECIMAL(8,6)para latitude (90 a -90 graus) e DECIMAL(9,6)longitude (180 a -180 graus). 6 casas decimais é bom para a maioria dos aplicativos. Ambos devem ser "assinados" para permitir valores negativos.


DECIMALO tipo é destinado a cálculos financeiros em que nenhum floor/ceilé aceito. Plain FLOATsupera significativamente DECIMAL.
Kondybas

1
@ Kondybas - Como o principal custo de um banco de dados é buscar linhas, a diferença de desempenho entre float e decimal não deve ser uma preocupação.
Rick James

14

Não é preciso ir muito longe, de acordo com o Google Maps, o melhor é o FLOAT (10,6) para lat e lng.


onde você conseguiu essa informação que eu não consigo encontrar? apenas no caso de algo mudar.
Webfacer 20/10/19

1
@webfacer, está na seção "Criando uma tabela no MySQL" aqui: developers.google.com/maps/documentation/javascript/… por exemplo lat FLOAT( 10, 6 ) NOT NULL, lng FLOAT( 10, 6 ) NOT NULL
turrican_34 27/10/19

1
@ webfacer, parece que a FLOATsintaxe está obsoleta a partir de mysql 8.0.17. O Mysql agora recomenda o uso FLOATsem parâmetros de precisão 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

Armazenamos latitude / longitude X 1.000.000 em nosso banco de dados oracle como NUMBERS para evitar erros de arredondamento com dobras.

Dado que a latitude / longitude até a sexta casa decimal era de 10 cm de precisão, tudo o que precisávamos. Muitos outros bancos de dados também armazenam lat / long até a sexta casa decimal.


2
Multiplicar por um número grande (como um milhão) é ótimo se você tiver muitos dados porque as operações inteiras (por exemplo, recuperação indexada) são muito mais rápidas que as flutuações.
Kaitlin Duck Sherwood

@KaitlinDuckSherwood - bits são bits - não conheço nenhum motivo para um float de 32 bits ser mais lento para recuperação (indexado ou não) do que um número inteiro de 32 bits. Até a matemática flutuante hoje em dia é rápida o suficiente para ser um problema. No entanto, concordo com o comentário de usar o multiplicador implícito com um número inteiro: ele maximiza a precisão que você obtém de 32 bits. Um pouco de prova de futuro à medida que a tecnologia melhora.
Página

6

Em uma perspectiva completamente diferente e mais simples:

Dessa forma, você não precisa se preocupar com a indexação de números e com todos os outros problemas associados aos tipos de dados que podem estragar suas coordenadas.


Nada de bom. OP disse que estaria realizando cálculos sobre os pares / GNL lat - suas respostas impede que
Yarin

4
@Yarin Essa é uma pergunta popular, na qual poucas (ou muitas) pessoas precisam apenas de uma resposta sobre como armazenar as coordenadas de acordo com suas próprias necessidades (muitas delas podem usar apenas os mapas do Google). Seu voto negativo sugere que esta resposta pode não ajudá-los ... Ao armazenar as coordenadas em uma string, eles saberão exatamente os valores originais que foram fornecidos a eles (por exemplo, pelo Google), que os ajudarão mais tarde se decidirem evoluir sua próprio aplicativo e faça cálculos neles. Naquele momento, eles ainda terão os dados brutos originais apenas porque não estragaram as conversões.
Armfoot

4

dependendo da sua aplicação, sugiro usar o FLOAT (9,6)

as teclas espaciais fornecerão mais recursos, mas nos benchmarks de produção os carros alegóricos são muito mais rápidos que as chaves espaciais. (0,01 VS 0,001 no AVG)


1
Você pode fornecer detalhes do resultado do teste aqui?
NameNotFoundException

4

O MySQL usa o dobro para todos os carros alegóricos ... Então use o tipo double. Usar float levará a valores arredondados imprevisíveis na maioria das situações


1
O MySQL realiza operações noDOUBLE . O MySQL permite que você armazene dados como 4 FLOATou 8 bytes DOUBLE. Portanto, é provável que haja uma perda de precisão ao armazenar uma expressão em uma FLOATcoluna.
Rick James

4

Embora não seja ideal para todas as operações, se você estiver criando blocos de mapas ou trabalhando com um grande número de marcadores (pontos) com apenas uma projeção (por exemplo, Mercator, como o Google Maps e muitas outras estruturas de mapas esperadas), eu descobri o que Eu chamo de "vasto sistema de coordenadas" para ser muito, muito útil. Basicamente, você armazena as coordenadas x e y de pixel com algum zoom - eu uso o nível de zoom 23. Isso tem vários benefícios:

  • Você faz a cara transformação de pixel lat / lng para mercator uma vez, e não sempre que lida com o ponto
  • Obter a coordenada do bloco a partir de um registro, dado o nível de zoom, leva um deslocamento à direita.
  • A obtenção da coordenada de pixel de um registro requer um deslocamento à direita e um AND bit a bit.
  • As mudanças são tão leves que é prático executá-las em SQL, o que significa que você pode executar um DISTINCT para retornar apenas um registro por local de pixel, o que reduzirá o número de registros retornados pelo back-end, o que significa menos processamento no a parte dianteira.

Falei sobre tudo isso em uma postagem recente do blog: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/


4

Estou muito surpreso com algumas respostas / comentários.

Por que diabos alguém estaria disposto a voluntariamente "pré-diminuir" a precisão e depois realizar cálculos com números piores? Parece estúpido.

Se a fonte tiver precisão de 64 bits, certamente seria estúpido fixar voluntariamente a escala para, por exemplo. 6 decimais e limite a precisão a um máximo de 9 dígitos significativos (o que acontece com o formato 9.6 decimal proposto com frequência).

Naturalmente, os dados são armazenados com a precisão que o material de origem possui. O único motivo para diminuir a precisão seria o espaço de armazenamento limitado.

  • Armazene os números de origem com precisão original
  • Armazene os números calculados a partir da fonte na precisão em que o cálculo ocorre (por exemplo, se o código de aplicação usar o dobro, armazene os resultados como o dobro)

O formato decimal 9.6 causa um fenômeno de encaixe na grade. Esse deve ser o último passo, se é que deve acontecer.

Eu não convidaria erros acumulados para o meu ninho.


2
Como a maioria das ferramentas e aplicativos de GPS tem precisão de apenas 6 casas decimais. Pointless para armazenar dados para uma precisão maior do que ferramentas pode medir gis.stackexchange.com/questions/8650/...
Yarin

1
@ Yarin Sim, de fato, mas você fala sobre medições e GPS, que não são mencionados na pergunta. Certamente existem números mais precisos. Mas vamos considerar o GPS; digamos, um conjunto de dados de origem de flutuadores de 64 bits, que já contém uma imprecisão. 6 casas decimais significa ajustar a latitude ao ca 11 centímetros mais próximo. Portanto, agora, apenas armazenando os dados (com 6 casas decimais), você abre uma possível imprecisão de 22 cm (se originalmente também 11 cm). Voluntariamente, provavelmente é necessário fazer um cálculo de 64 bits antes de talvez armazenar uma terceira vez - agora janela de imprecisão de 33 cm, + -16 cm. Parece idiota, imho.
Stormwind

@ Rick James eu provavelmente armazená-lo como 64 bits, ou seja. 0.3333333333333333. Nós falamos geodados, certo? "1/3" raramente aparece na natureza, onde as coisas são normalmente medidas, com uma precisão razoável.
Stormwind

4

TL; DR

Use FLOAT (8,5) se você não estiver trabalhando na NASA / militar e não estiver fabricando sistemas navi de aeronaves.


Para responder sua pergunta completamente, você precisa considerar várias coisas:

Formato

  • graus minutos segundos : 40 ° 26 ′ 46 ″ N 79 ° 58 ′ 56 ″ W
  • graus minutos decimais : 40 ° 26,767 ′ N 79 ° 58,933 ′ W
  • graus decimais 1 : 40,446 ° N 79,982 ° W
  • graus decimais 2 : -32,60875, 21,27812
  • Algum outro formato caseiro? Ninguém o proíbe de criar seu próprio sistema de coordenadas centrado em casa e o armazena como orientação e distância de sua casa. Isso pode fazer sentido para alguns problemas específicos em que você está trabalhando.

Portanto, a primeira parte da resposta seria: você pode armazenar as coordenadas no formato que seu aplicativo usa para evitar conversões constantes e fazer consultas SQL mais simples.

Provavelmente você usa o Google Maps ou OSM para exibir seus dados, e o GMaps está usando o formato "graus decimais 2". Portanto, será mais fácil armazenar coordenadas no mesmo formato.

Precisão

Em seguida, você deseja definir a precisão necessária. Claro que você pode armazenar coordenadas como "-32.608697550570334,21.278081997935146", mas você já se importou com milímetros enquanto navegava até o ponto? Se você não trabalha na NASA e não faz trajetórias de satélites, foguetes ou aviões, deve ficar bem com vários metros de precisão.

O formato comumente usado é de 5 dígitos após pontos, o que fornece 50 cm de precisão.

Exemplo : existe uma distância de 1 cm entre X, 21.278081 8 e X, 21.278081 9 . Portanto, 7 dígitos após o ponto fornecem precisão de 1/2 cm e 5 dígitos após o ponto fornecem precisão de 1/2 metro (porque a distância mínima entre pontos distintos é de 1m, o erro de arredondamento não pode ser mais da metade). Para a maioria dos propósitos civis, deve ser suficiente.

O formato de graus decimais em minutos (40 ° 26.767 ′ N 79 ° 58.933 ′ W) fornece exatamente a mesma precisão que 5 dígitos após o ponto

Armazenamento com espaço eficiente

Se você selecionou o formato decimal, sua coordenada é um par (-32.60875, 21.27812). Obviamente, 2 x (1 bit para sinal, 2 dígitos para graus e 5 dígitos para expoente) será suficiente.

Então, aqui gostaria de apoiar Alix Axel a partir de comentários dizendo que a sugestão do Google para armazená-lo no FLOAT (10,6) é realmente extra, porque você não precisa de 4 dígitos para a parte principal (já que o sinal é separado e a latitude é limitada) a 90 e a longitude é limitada a 180). Você pode facilmente usar FLOAT (8,5) para precisão de 1 / 2m ou FLOAT (9,6) para precisão de 50 / 2cm. Ou você pode até armazenar lat e long em tipos separados, porque FLOAT (7,5) é suficiente para lat. Consulte a referência de tipos de float do MySQL. . Qualquer um deles será como FLOAT normal e igual a 4 bytes de qualquer maneira.

Normalmente, o espaço não é um problema hoje em dia, mas se você realmente deseja otimizar o armazenamento por algum motivo (Isenção de responsabilidade: não faça pré-otimização), pode compactar lat (não mais que 91.000 valores + sinal) + longo (não mais de 181 000 valores + sinal) a 21 bits, significativamente menor que 2xFLOAT (8 bytes == 64 bits)


3

As funções espaciais no PostGIS são muito mais funcionais (ou seja, não restritas às operações do BBOX) do que aquelas nas funções espaciais do MySQL. Confira: link text


1
  1. As latitudes variam de -90 a +90 (graus), portanto DECIMAL (10, 8) é aceitável para isso.

  2. as longitudes variam de -180 a +180 (graus), então você precisa de DECIMAL (11, 8).

Nota: O primeiro número é o número total de dígitos armazenados e o segundo é o número após o ponto decimal.

Em resumo: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL



-2

Os cálculos de Lat Long requerem precisão, portanto, use algum tipo de tipo decimal e faça com que a precisão seja pelo menos 2 maior que o número que você armazenará para realizar cálculos matemáticos. Eu não sei sobre os meus tipos de dados sql, mas no SQL Server as pessoas costumam usar float ou real em vez de decimal e se metem em problemas porque esses são números estimados e não reais. Portanto, verifique se o tipo de dados que você usa é um tipo decimal verdadeiro e não um tipo decimal flutuante e você deve estar bem.


1
os tipos float e decimal têm seu lugar. Como regra geral, floats significam variáveis ​​físicas e decimais são para entidades contáveis ​​(principalmente dinheiro). eu não vejo por que você preferir decimal para lat / long
Javier

1
Eu também acho que float é bom para lat / long. Pelo menos no SQL Server (4 bytes, 7 dígitos).
Dragoljub Ćurčić

O flutuador não é exato, calcula-se, o lago de exatidão em um lat long é fatal! Poderia apontar para um lugar completamente diferente no mundo.
HLGEM

2
O erro máximo dos tipos de dados flutuantes é baixo o suficiente para que isso não seja um problema. Quero dizer, você deve estar ciente da multiplicação / acumulação de erros com as duas implementações de qualquer maneira.
Aranha

@HLGEM - O arredondamento para algum número de casas decimais também o leva a um local diferente do globo. A questão é se esse ponto diferente está tão próximo que não importa.
Rick James

-3

A FLOATdeve fornecer toda a precisão necessária e ser melhor para as funções de comparação do que armazenar cada coordenada como uma string ou algo parecido.

Se sua versão do MySQL for anterior à 5.0.3, talvez você precise prestar atenção em certos erros de comparação de ponto flutuante .

Antes do MySQL 5.0.3, as colunas DECIMAL armazenam valores com precisão exata, porque são representados como strings, mas os cálculos nos valores DECIMAL são feitos usando operações de ponto flutuante. A partir da versão 5.0.3, o MySQL executa operações DECIMAL com uma precisão de 64 dígitos decimais, o que deve resolver os problemas de imprecisão mais comuns quando se trata de colunas DECIMAL


2
Você precisa de um tipo de dados de coordenadas de latitude / longitude real para facilitar a matemática. Imagine a conveniência de algo como o equivalente a "selecionar * de lojas onde a distância (lojas.localização, minhalocação) <5 milhas"
Kirk Strauser

1
Não tinha ouvido falar das extensões espaciais antes, isso parece muito conveniente, pois já havia trabalhado em um aplicativo herdado que faz alguns cálculos relacionados a áreas geográficas, deve verificar.
ConroyP 01/10/08

@ConroyP - Não. Essa citação está indicando que DECIMALhavia (antes da versão 5.0.3) certos erros devido ao uso da implementação flutuante.
Rick James
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.