Quel type de données utiliser lors du stockage de données de latitude et de longitude dans des bases de données SQL?

Lorsque vous stockez des données de latitude ou de longitude dans une firebase database compatible ANSI SQL, quel type de données serait le plus approprié? Le float devrait float être utilisé, ou decimal , ou …?

Je suis conscient que Oracle, MySQL et SQL Server ont ajouté des types de données spécifiques pour le traitement des données géo, mais je voudrais savoir comment stocker les informations dans une firebase database SQL “plain vanilla”.

Decimal(9,6)

Si vous n’êtes pas habitué aux parameters de précision et d’échelle, voici un visuel de chaîne de format:

###.######

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

Eh bien, vous avez demandé comment stocker Latitude / Longitude et ma réponse est la suivante: n’utilisez pas le WGS 84 (en Europe ETRS 89 ), car il s’agit de la norme pour les références Geo.

Mais mis à part ce détail, j’ai utilisé un type défini par l’utilisateur avant que SQL 2008 n’inclue enfin la prise en charge géo.

Dans vanilla Oracle, la fonctionnalité appelée LOCATOR (une version paralysée de Spatial) nécessite que les données de coordonnées soient stockées en utilisant le type de données NUMBER (sans précision). Lorsque vous essayez de créer des index basés sur les fonctions pour prendre en charge les requêtes spatiales, cela risque de générer des erreurs.

Vous pouvez facilement stocker un nombre décimal de lat / lon dans un champ entier non signé, au lieu de le diviser en entier et en partie décimale et de les stocker séparément, comme cela est 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 unsigned int (10) , cela fonctionne aussi bien dans mysql que dans sqlite, qui est sans typage.

Grâce à l’expérience, je trouve que cela fonctionne très vite, si tout ce que vous avez besoin de faire est de stocker les coordonnées et de récupérer celles 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 avec des entiers. (ex: pour mettre en cache un résultat de géocode). J'espère que cela ajoute de la valeur à la discussion.

Une autre application pourrait ê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 profiter 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 */ 

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

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

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

Si vous convertissez souvent vers / à partir de la notation de fraction degºmin’sec, j’envisagerai de stocker chaque valeur en tant que type entier (smallint, tinyint, tinyint, smallint?).

Vous devriez jeter un coup d’œil aux nouveaux types de données spatiales introduits dans SQL Server 2008. Ils ont été spécifiquement conçus pour ce type de tâche et facilitent l’indexation et l’interrogation des données.

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