web-dev-qa-db-fra.com

Quel type de données MySQL doit être utilisé pour Latitude/Longitude avec 8 décimales?

Je travaille avec des données cartographiques et le Latitude/Longitude s'étend jusqu'à 8 décimales. Par exemple:

Latitude 40.71727401
Longitude -74.00898606

J'ai vu dans le document Google Qui utilise: 

lat FLOAT( 10, 6 ) NOT NULL,  
lng FLOAT( 10, 6 ) NOT NULL

cependant, leurs décimales ne vont pas jusqu'à 6.
Devrais-je utiliser FLOAT(10, 8) ou existe-t-il une autre méthode à considérer pour stocker ces données afin qu'elles soient précises Il sera utilisé avec les calculs de carte. Merci!

189
Edward

DECIMAL est le type de données MySQL pour l'arithmétique exacte. Contrairement à FLOAT, sa précision est fixe pour toute taille de nombre. Ainsi, en l’utilisant à la place de FLOAT, vous éviterez les erreurs de précision lors de certains calculs. Si vous ne faites que stocker et récupérer les nombres sans calcul, alors dans la pratique, FLOAT serait sûr, bien que l'utilisation de DECIMAL ne présente aucun danger. Avec des calculs, FLOAT est toujours correct, mais il faut être absolument sûr de 8d.p. précision, vous devez utiliser DECIMAL.

Les latitudes varient de -90 à +90 (degrés), donc DECIMAL (10, 8) convient, mais les longitudes vont de -180 à +180 (degrés), vous avez donc besoin de DECIMAL (11, 8). Le premier nombre correspond au nombre total de chiffres enregistrés et le second au nombre situé après le point décimal.

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

Ceci explique le fonctionnement de MySQL avec les types de données à virgule flottante.

475
gandaliter

De plus, vous verrez que les valeurs float sont arrondies.

 // exemple: valeurs données 41.0473112,29.0077011 

 float (11,7) | décimal (11,7) 
 --------------------------- 
 41.0473099 | 41.0473112 
 29.0077019 | 29.0077011 

12
K-Gun

Vous pouvez définir votre type de données comme entier signé. Lorsque vous stockez les coordonnées dans SQL, vous pouvez définir lat * 10000000 et long * 10000000. Et lorsque vous sélectionnez distance/rayon, vous divisez les coordonnées de stockage en 10000000. Je l’ai testé avec 300 000 lignes, le temps de réponse à la requête est bon. (2 x CPU 2,67 GHz, 2 Go de RAM, MySQL 5.5.49)

6

N'utilisez pas de float ... Il arrondira vos coordonnées, ce qui entraînera des événements étranges.

Utilisez décimal

2
Sam Sabey

en laravel utilisé colonne décimale type pour la migration

$table->decimal('latitude', 10, 8);
$table->decimal('longitude', 11, 8);

pour plus d'informations voir type de colonne disponible

2
Jignesh Joisar

La meilleure façon dans mon cas était de sauvegarder les coordonnées en tant que DOUBLE.

lat DOUBLE NOT NULL,  
lng DOUBLE NOT NULL

Cela économisera la valeur entière sans arrondir.

Si vous devez arrondir la valeur, mon conseil est que ce traitement est effectué à l'origine des données, par exemple dans l'interface utilisateur.

1
tioperez

MySQL supporte maintenant les types de données spatiales depuis que cette question a été posée. La réponse acceptée actuellement n’est donc pas fausse, mais si vous recherchez des fonctionnalités supplémentaires, telles que la recherche de tous les points d’un polygone donné, utilisez le type de données POINT.

Consultez la documentation Mysql sur les types de données géospatiales et les fonctions d'analyse spatiale

1
Bill--

Utiliser Migration de Ruby on Rails

class CreateNeighborhoods < ActiveRecord::Migration[5.0]
  def change
    create_table :neighborhoods do |t|
      t.string :name
      t.decimal :latitude, precision: 15, scale: 13
      t.decimal :longitude, precision: 15, scale: 13
      t.references :country, foreign_key: true
      t.references :state, foreign_key: true
      t.references :city, foreign_key: true

      t.timestamps
    end
  end
end
0
gilcierweb

Je pense que le meilleur moyen de stocker Lat/Lng dans MySQL est d’avoir une colonne POINT (type de données 2D) avec un index SPATIAL.

CREATE TABLE `cities` (
  `Zip` varchar(8) NOT NULL,
  `country` varchar (2) GENERATED ALWAYS AS (SUBSTRING(`Zip`, 1, 2)) STORED,
  `city` varchar(30) NOT NULL,
  `centre` point NOT NULL,
  PRIMARY KEY (`Zip`),
  KEY `country` (`country`),
  KEY `city` (`city`),
  SPATIAL KEY `centre` (`centre`)
) ENGINE=InnoDB;


INSERT INTO `cities` (`Zip`, `city`, `centre`) VALUES
('CZ-10000', 'Prague', POINT(50.0755381, 14.4378005));
0
dayvee.cz