web-dev-qa-db-fra.com

Quel type de données utiliser pour stocker des données de latitude et de longitude dans des bases de données SQL?

Lors du stockage de données de latitude ou de longitude dans une base de données compatible ANSI SQL, quel type de données serait le plus approprié? Faut-il utiliser float ou decimal ou ...?

Je suis conscient du fait qu'Oracle, MySql et SQL Server ont ajouté des types de données spéciaux spécifiquement pour la gestion des données géographiques, mais je voudrais savoir comment stocker ces informations dans une base de données SQL "plain Vanilla".

288
dthrasher

Decimal(9,6)

Si vous n’êtes pas habitué aux paramètres de précision et d’échelle, voici un visuel de format:

###.######

412
dotjoe

Nous utilisons float, mais toute variante numérique comportant 6 décimales devrait également fonctionner.

5
Keith

Eh bien, vous avez demandé comment enregistrer la latitude/longitude et ma réponse est la suivante: non, vous pouvez envisager d’utiliser le WGS 84 (en Europe ETRS 89 ) car c’est le norme pour les références géographiques.

Mais, mis à part ce détail, j’ai utilisé un type défini par l’utilisateur dans les jours qui ont précédé l’introduction du support géographique par SQL 2008.

3
Kasper

Vous pouvez facilement stocker un nombre décimal lat/lon dans un champ entier non signé, au lieu de les diviser en une partie entière et décimale et de les stocker séparément, comme suggéré ici, en utilisant l'algorithme de conversion suivant:

en tant que fonction mysql stockée:

CREATE DEFINER=`r`@`l` FUNCTION `PositionSmallToFloat`(s INT) 
RETURNS decimal(10,7)
DETERMINISTIC
RETURN if( ((s > 0) && (s >> 31)) , (-(0x7FFFFFFF - 
(s & 0x7FFFFFFF))) / 600000, s / 600000)

et retour

CREATE DEFINER=`r`@`l` FUNCTION `PositionFloatToSmall`(s DECIMAL(10,7)) 
RETURNS int(10)
DETERMINISTIC
RETURN s * 600000

Cela doit être stocké dans un nsigned int (10), cela fonctionne aussi bien dans mysql que dans sqlite, qui est sans type.

par expérience, je trouve que cela fonctionne très vite, si tout ce que vous avez à faire est de stocker les coordonnées et de les récupérer pour faire des calculs.

en php ces 2 fonctions ressemblent

function LatitudeSmallToFloat($LatitudeSmall){
   if(($LatitudeSmall>0)&&($LatitudeSmall>>31)) 
     $LatitudeSmall=-(0x7FFFFFFF-($LatitudeSmall&0x7FFFFFFF))-1;
   return (float)$LatitudeSmall/(float)600000;
}

et retour:

function LatitudeFloatToSmall($LatitudeFloat){
   $Latitude=round((float)$LatitudeFloat*(float)600000);
   if($Latitude<0) $Latitude+=0xFFFFFFFF;
   return $Latitude;
}

Cela présente également un avantage supplémentaire en termes de création, par exemple, de clés uniques memcached avec des entiers. (ex: mettre en cache un résultat de géocodage). J'espère que cela ajoute de la valeur à la discussion.

Une autre application peut être lorsque vous n'avez pas d'extensions SIG et que vous voulez simplement conserver quelques millions de ces paires lat/lon. Vous pouvez utiliser des partitions sur ces champs dans mysql pour bénéficier du fait qu'elles sont des entiers:

Create Table: CREATE TABLE `Locations` (
  `lat` int(10) unsigned NOT NULL,
  `lon` int(10) unsigned NOT NULL,
  `location` text,
  PRIMARY KEY (`lat`,`lon`) USING BTREE,
  KEY `index_location` (`locationText`(30))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY ()
PARTITIONS 100 */
2
Glenn Plas

Dans Vanilla Oracle, la fonctionnalité appelée LOCATOR (une version handicapée de Spatial) nécessite que les données de coordonnées soient stockées sous le type de données NUMBER (aucune précision). Lorsque vous essayez de créer des index basés sur les fonctions pour prendre en charge les requêtes spatiales, il en va autrement.

2
Larry

Jetez un coup d'œil aux nouveaux types de données Spatial introduits dans SQL Server 2008. Ils sont spécialement conçus pour ce type de tâche et rendent l'indexation et l'interrogation des données beaucoup plus simples et plus efficaces.

http://msdn.Microsoft.com/en-us/library/bb933876 (v = sql.105) .aspx

http://blogs.technet.com/andrew/archive/2007/11/26/sql-server-2008-spatial-data-types.aspx

1
syed Ahsan Jaffri

Je voudrais utiliser un nombre décimal avec la précision appropriée pour vos données.

1
Sam

Je pense que cela dépend des opérations que vous devrez effectuer le plus souvent.

Si vous avez besoin de la valeur complète sous forme de nombre décimal, utilisez décimal avec la précision et l'échelle appropriées. Flotter va bien au-delà de vos besoins, je crois.

Si vous convertissez souvent la notation en fraction vers/depuis degºmin'sec, il serait utile de stocker chaque valeur sous forme de type entier (smallint, tinyint, tinyint, smallint?).

1
jpj625