Какой тип данных использовать при хранении данных широты и долготы в базах данных SQL? [дубликат]
этот вопрос уже есть ответ здесь:
каков идеальный тип данных для использования при хранении широты / долготы в базе данных MySQL?
19 ответов
при хранении данных широты или долготы в базе данных, совместимой с ANSI SQL, какой тип данных будет наиболее подходящим? Должен float или decimal, или ...?
Я знаю, что Oracle, MySql и SQL Server добавили некоторые специальные типы данных специально для обработки гео данных, но мне интересно, как вы будете хранить информацию в "простой ванильной" базе данных SQL.
8 ответов:
Decimal(9,6)Если вы не привыкли к точности и масштабированию параметров, вот визуальный формат строки:
###.######
в vanilla Oracle функция, называемая LOCATOR (искалеченная версия Spatial), требует, чтобы данные координат хранились с использованием типа данных NUMBER (без точности). При попытке создать индексы на основе функций для поддержки пространственных запросов он будет кляп в противном случае.
вы можете легко хранить десятичное число lat/lon в целочисленном поле без знака, вместо того, чтобы разбивать их на целочисленную и десятичную части и хранить их отдельно, как несколько предложено здесь, используя следующий алгоритм преобразования:
как сохраненная функция mysql:
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)и обратно
CREATE DEFINER=`r`@`l` FUNCTION `PositionFloatToSmall`(s DECIMAL(10,7)) RETURNS int(10) DETERMINISTIC RETURN s * 600000Это должно быть сохранено в unsigned int (10), это работает в mysql, а также в sqlite, который является без шрифта.
по опыту я считаю, что это работает очень быстро, если все, что вам нужно, это хранить координаты и извлекать их, чтобы сделать некоторую математику.
в php эти 2 функции выглядят как
function LatitudeSmallToFloat($LatitudeSmall){ if(($LatitudeSmall>0)&&($LatitudeSmall>>31)) $LatitudeSmall=-(0x7FFFFFFF-($LatitudeSmall&0x7FFFFFFF))-1; return (float)$LatitudeSmall/(float)600000; }и снова:
function LatitudeFloatToSmall($LatitudeFloat){ $Latitude=round((float)$LatitudeFloat*(float)600000); if($Latitude<0) $Latitude+=0xFFFFFFFF; return $Latitude; }это имеет некоторые дополнительные преимущества, а также в плане создания, например, memcached уникальных ключей с целыми числами. (например, для кэширования результатов геокодирования). Надеюсь, что это добавляет ценность дискуссии.
другой приложение может быть, когда вы без расширений ГИС и просто хотите сохранить несколько миллионов этих пар lat/lon, вы можете использовать разделы на этих полях в mysql, чтобы извлечь выгоду из того, что они являются целыми числами:
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 */
Я думаю, что это зависит от операций, которые вам нужно будет делать чаще всего.
Если вам нужно полное значение в виде десятичного числа, то используйте десятичное с соответствующей точностью и масштабом. Поплавок-это далеко за пределами ваших потребностей, я считаю.
Если вы будете часто преобразовывать в / из нотации фракции degºmin'SEC, я бы рассмотрел сохранение каждого значения как целочисленного типа (smallint, tinyint, tinyint, smallint?).
вы должны взглянуть на новые типы пространственных данных, которые были введены в SQL Server 2008. Они специально разработаны для такого рода задач и делают индексацию и запрос данных намного проще и эффективнее.
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
Comments