Quel type de données utiliser pour stocker les données de latitude et de longitude dans les bases de données SQL? [dupliquer]
cette question a déjà une réponse ici:
- Quel est le type de données idéal pour stocker latitude / longitude dans une base de données MySQL? 19 réponses
lors du stockage des données de latitude ou de longitude dans une base de données conforme ANSI SQL, quel type de données serait le plus approprié? Doit être utilisé float
, ou decimal
, ou ...?
Je suis conscient Qu'Oracle, MySql, et SQL Server ont ajouté des types de données spéciales spécifiquement pour le traitement des données géographiques, mais je suis intéressé par la façon dont vous stockeriez l'information dans une base de données SQL" simple vanilla".
8 réponses
Decimal(9,6)
si vous n'êtes pas habitué aux paramètres de précision et d'échelle, voici une chaîne de format visuel:
###.######
nous utilisons float, mais toute saveur de numérique avec 6 décimales devrait également fonctionner.
Eh bien, vous avez demandé comment stocker la Latitude/Longitude et ma réponse est: ne le faites pas, vous pourriez envisager d'utiliser le WGS 84 ( en Europe ETRS 89 ) comme il est la norme pour les références géographiques.
mais ce détail mis à part, j'ai utilisé un type défini par L'utilisateur dans les jours avant SQL 2008 finalement inclure le soutien geo.
dans vanilla Oracle, la fonctionnalité appelée Localisateur (une version invalidée de Spatial) exige que les coordonnées soient stockées en utilisant le type de données de numéro (aucune précision). Lorsque vous essayez de créer des index basés sur des fonctions pour supporter les requêtes spatiales, il va bâillonner autrement.
vous pouvez facilement stocker un nombre décimal lat/lon dans un champ entier non signé, au lieu de les séparer dans un entier et une partie décimale et stocker ceux-ci séparément comme un peu suggéré ici en utilisant l'algorithme de conversion suivant:
comme une 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
qui doit être stocké dans un non signé int(10) , cela fonctionne aussi dans mysql comme dans sqlite qui est typeless.
par expérience, je trouve que cela fonctionne très vite, si tout ce que vous avez besoin de stocker est coordonnées et de récupérer ceux de faire des maths 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 une fois de plus:
function LatitudeFloatToSmall($LatitudeFloat){
$Latitude=round((float)$LatitudeFloat*(float)600000);
if($Latitude<0) $Latitude+=0xFFFFFFFF;
return $Latitude;
}
cela a un avantage supplémentaire aussi bien en terme de création par exemple des Clés uniques memcached avec des entiers. (ex: pour mettre en cache un géocode résultat.) Espérons que cela ajoute de la valeur à la discussion.
une autre application pourrait être quand vous êtes sans extensions GIS et que vous voulez simplement garder quelques millions de ces paires lat/lon, vous pouvez utiliser des partitions sur ces champs dans mysql pour bénéficier du fait qu'ils sont 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 */
j'utiliserais une décimale avec la précision appropriée pour vos données.
je pense que cela dépend des opérations que vous devrez faire le plus souvent.
si vous avez besoin de la pleine valeur comme nombre décimal, puis utiliser décimal avec la précision et l'échelle appropriées. Le char est au-delà de vos besoins, je crois.
si vous convertissez souvent en/de la notation de la fraction de degºmin'sec", j'envisagerais de stocker chaque valeur comme un type entier (smallint, tinyint, tinyint, smallint?).
vous devriez jeter un oeil aux nouveaux types de données spatiales qui ont été introduits dans SQL Server 2008. Ils sont spécialement conçus pour ce genre de tâche et rendent l'indexation et la consultation des données beaucoup plus faciles 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