Quel type de données à utiliser pour stocker des données de latitude et de longitude dans les bases de données SQL? [dupliquer]

StackOverflow https://stackoverflow.com/questions/1196415

Question

    

Cette question a déjà une réponse ici:

         

Lors du stockage des données de latitude ou de longitude dans une base de données compatible ANSI SQL, ce type de données serait le plus approprié? Si float être utilisé, ou decimal, ou ...?

Je suis conscient que Oracle, MySql et SQL Server ont ajouté quelques types de données spéciales spécifiquement pour le traitement des données géo, mais je suis intéressé par la façon dont vous stocker les informations dans une base de données SQL « plain vanilla ».

Était-ce utile?

La solution

Decimal(9,6)

Si vous n'êtes pas habitué à la précision et paramètres échelle, voici une chaîne de format visuel:

###.######

Autres conseils

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

Eh bien, vous avez demandé comment stocker Latitude / Longitude et ma réponse est: ne pas, vous pouvez envisager d'utiliser la WGS 84 (en Europe ETRS 89 ) car il est la norme des références Geo.

Mais ce détail mis à part, j'ai utilisé un type défini par l'utilisateur dans les jours avant que SQL 2008 comprennent enfin un support géo.

Dans la vanille Oracle, la fonctionnalité appelée LOCATOR (une version limitée de l'espace) exige que les données soient stockées coordonnées en utilisant le type de données NUMBER (pas de précision). Lorsque vous essayez de créer des index basés sur des fonctions pour soutenir les requêtes spatiales il va gag autrement.

Vous pouvez facilement stocker une latitude / longitude nombre décimal dans un champ entier non signé, au lieu de les diviser en un entier et une partie décimale et stocker les séparément comme un peu suggéré d'utiliser ici l'algorithme de conversion suivant:

en fonction de 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

Il doit être stocké dans un entier non signé (10) , cela fonctionne dans une base MySQL, ainsi que dans sqlite qui est sans type.

par l'expérience, je trouve que cela fonctionne très vite, si tout ce que vous devez est de coordonnées de stocker et de récupérer les faire quelques calculs avec.

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 a un certain avantage supplémentaire aussi bien en terme de créer par exemple des clés Memcached uniques avec des nombres entiers. (Ex: pour mettre en cache un résultat de géocodage). Espérons que cela apporte une valeur ajoutée à la discussion.

Une autre application pourrait être quand vous êtes sans extensions SIG et que vous voulez simplement garder quelques millions de ces paires latitude / longitude, vous pouvez utiliser des partitions sur les champs de MySQL pour tirer profit du fait qu'ils 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 une décimale avec la précision appropriée pour vos données.

Je pense que cela dépend des opérations que vous serez besoin de faire le plus souvent.

Si vous avez besoin de la pleine valeur en tant que nombre décimal, puis utilisez décimal avec une précision et une échelle appropriée. Flotteur est bien au-delà de vos besoins, je crois.

Si vous convertira à / de la notation de fraction degºmin'sec "souvent, je considère stocker chaque valeur en tant que type entier (smallint, tinyint, tinyint, smallint?).

Vous devriez jeter un oeil sur les nouvelles données spatiales types qui ont été introduites dans SQL Server 2008. Ils sont spécialement conçus ce genre de tâche et de faire l'indexation et l'interrogation des données beaucoup plus facile et plus efficace.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top