База данных /SQL: как хранить данные о долготе/широте?

Вопрос о производительности...

У меня есть база данных домов, в которых есть данные геолокации (долгота и широта).

Что я хочу сделать, это найти лучший способ хранения локальных данных в моем MySQL (v5.0.24a) с использованием базы данных InnoDB, чтобы я мог выполнять множество запросов, где я возвращаю все домашние записи которые находятся между x1 и x2 latitude и y1 и y2 longitude.

В настоящее время моя схема базы данных

---------------------
Homes   
---------------------
geolat - Float (10,6)
geolng - Float (10,6)
---------------------

И мой запрос:

SELECT ... 
WHERE geolat BETWEEN x1 AND x2
AND geolng BETWEEN y1 AND y2
  • Это то, что я описал выше, лучший способ сохранить данных широты и долготы в MySQL с использованием Float (10,6) и выделения долготы/широты? Если нет, то что? Существуют типы Float, Decimal и даже Spatial в качестве типа данных.
  • Это лучший способ выполнить SQL с точки зрения производительности? Если нет, то что?
  • Использует ли другой MySQL двигатель базы данных имеет смысл?

ОБНОВЛЕНИЕ: еще без ответа

У меня есть 3 разных ответа ниже. Один человек говорит, чтобы использовать Float. Один человек говорит использовать INT. Один человек говорит использовать Spatial.

Итак, я использовал инструкцию MySQL "EXPLAIN" для измерения скорости выполнения SQL. По-видимому, при использовании INT или Float для типа данных долготы и широты существует абсолютно никакой разницы в выполнении SQL (выбор набора результатов).

Также представляется, что использование оператора < BETWEEN является СУЩЕСТВУЮЩИМ быстрее, чем использование операторов SQL > "или <". Он почти в 3 раза быстрее использовал "BETWEEN", чем использовать инструкцию ">" и "<".

С учетом сказанного я по-прежнему считаю, что влияние производительности будет связано с использованием Spatial, поскольку он неясен для меня, если он поддерживается моей версией MySQL (v5.0.24)... а также как я включаю он, если поддерживается.

Любая помощь будет очень восприимчивой

Ответ 1

float (10,6) просто отлично.

Любые другие схемы свернутого хранения потребуют большего количества переводов, и математика с плавающей запятой будет довольно быстрой.

Ответ 2

Я знаю, что вы спрашиваете о MySQL, но если пространственные данные важны для вашей компании, вам может потребоваться пересмотреть. PostgreSQL + PostGIS - также бесплатное программное обеспечение, и у них отличная репутация для эффективного управления пространственными и географическими данными. Многие используют PostgreSQL только из-за PostGIS.

Я мало знаю о пространственной системе MySQL, поэтому, возможно, он работает достаточно хорошо для вашего прецедента.

Ответ 3

Проблема с использованием любого другого типа данных, кроме "пространственного" здесь, заключается в том, что ваш "прямоугольный выбор" может (как правило, это зависит от того, насколько ярка ваша СУБД), а MySQL, безусловно, не самый яркий) оптимизированы в одном измерении.

Система может выбрать либо индекс долготы, либо индекс широты, и использовать его для уменьшения набора проверяемых строк. Но после того, как это было сделано, есть выбор: (a) выборки всех найденных строк и их сканирование и проверка на "другое измерение" или (б) выполнение аналогичного процесса в "другом измерении", а затем сопоставляя эти два набора результатов, чтобы увидеть, какие строки отображаются в обоих. Этот последний вариант не может быть реализован как таковой в вашем конкретном СУБД.

Пространственные индексы сортируют последнее "автоматически", поэтому я считаю, что можно с уверенностью сказать, что пространственный индекс даст лучшую производительность в любом случае, но также может быть, что он не значительно превзошел другие решений, и что это просто не стоит беспокоить. Это зависит от всех видов вещей, таких как объем и распределение в ваших фактических данных и т.д. И т.д.

Конечно, индексы float (tree) по необходимости медленнее, чем целые индексы, из-за более длительного времени, которое обычно требуется для выполнения ' > ' на поплавках, чем для целых чисел. Но я был бы удивлен, если бы этот эффект был действительно заметным.

Ответ 4

Я бы сохранил его как целые числа (int, 4 байта), представленные в 1/1,000,000th градусов. Это даст вам разрешение в несколько дюймов.

Я не думаю, что в MySQL есть встроенный пространственный тип данных.

Ответ 5

Поплавок (10,6)

Где широта или долгота 5555.123456?

Разве вы не имеете в виду Float (9,6)?

Ответ 6

Google использует float (10,6) в своем примере "Store locator". Это достаточно для меня, чтобы пойти с этим.

fooobar.com/questions/18909/...

Кроме того, начиная с MySQL 5.6.x, поддержка пространственных расширений намного лучше и сопоставима с PostGIS в функциях и производительности.

Ответ 8

У меня есть та же самая схема (float (10,6)) и запрос (выбор внутри прямоугольника), и я обнаружил, что переключение db-движка из innoDB в myisam удваивает скорость для "точки в прямоугольном поиске", в таблице с 780 000 записей.

Кроме того, я преобразовал все значения lng/lat в декартовые целые числа (x, y) и создал индекс с двумя столбцами на x, y, а моя скорость переместилась от ~ 27 мс до 1,3 мс для одного и того же вида.

Ответ 9

Это зависит от того, как вы используете данные. Но при грубом чрезмерном упрощении фактов десятичное число быстрее, но менее точное в приближениях. Подробнее здесь:

http://msdn.microsoft.com/en-us/library/aa223970(SQL.80).aspx

Кроме того, стандарт для GPS-координат указан в ISO 6709:

http://en.wikipedia.org/wiki/ISO_6709