Який ідеальний тип даних використовувати для зберігання широти / довготи в базі даних MySQL?


431

Маючи на увазі, що я буду виконувати обчислення на лат / довгих парах, який тип даних найкраще підходить для використання з базою даних MySQL?


1
Я вважаю це посилання дуже корисним: howto-use-mysql-spatial-ext.blogspot.com/2007/11/… Це може бути трохи старше, але воно містить повне пояснення, включаючи приклади.
madc

Імхо більшість людей тут не розуміє, що відбувається. Як тільки код програми торкнеться числа, за умови використання подвійних (що більшість), число перетворюється на щонайменше подвійну точність . Збереження його тоді, навіть мільйон десятків, не принесе користі. Збереження його з обмеженою кількістю десяткових знаків (наприклад, 6) знищує частину цієї точності і додає накопичену помилку щоразу, коли вона переписується в базу даних . Двійник містить 16 значних чисел, потенційно всі десятичні знаки. Видалення 10 з них створює накопичену помилку з часом. Це "плаваюча точка" з причини. Проти.
Stormwind

Продовження: 6 десяткових знаків може бути нормальним, якщо зберігати фігуру, придбану із зовнішнього джерела, без змін та вперше - як вихідний матеріал. Але якщо виконувати обчислення на ньому навіть один раз і зберігати його знову, то німецьку частину його точності видалити, застосувавши певний десятковий формат. Виконання обчислення виключно всередині сервера може бути різним (сервер може або не може використовувати щось інше, ніж внутрішнє подвоєння), а використання гірших числових представлень, ніж подвійне в додатку, обчислення ofc зменшує потребу в точності зберігання однаково.
Stormwind

Проти: Якщо сервер зберігає номер з більш високою точністю, незважаючи на заявлену "9.6" (що я не знаю, чи є), то нічого з цього немає значення, а формат є суто справою зручності - мало робити з питаннями точності. Але я не був би здивований, якщо сервер насправді округляє будь-яке число до точності в 6 десятків із таким форматом.
Stormwind

Cont: Нарешті: Для широта, довгота - х, 6 - десяткове це питання клацати в ок 11-сантиметрова сітка. Кожного разу, коли хтось читає (торкається), обчислює та зберігає знову, з 6 десяткових знаків, відбудеться нове оснащення (= накопичена помилка). Якщо всі помилки йдуть в одному напрямку, буде велика помилка. Якщо виконувати на ньому тимчасові множення (наприклад, масштабувати вгору, віднімати і зменшувати вниз), воно може зростати ще більше. Не обробляйте точність без гарного расону!
Stormwind

Відповіді:


161

Використовуйте просторові розширення MySQL за допомогою GIS.


25
Чи є у вас інші посилання на приклади чи будь-яку іншу інформацію про те, як найкраще почати з ними?
Codebeef

6
MYSQL Spatial є хорошим варіантом, але все ще має значні обмеження та застереження (станом на 6). Будь ласка, дивіться мою відповідь нижче ...
Джеймс Шек

1
@James Schek має рацію. Крім того, MySQL виконує всі свої обчислення за допомогою евклідової геометрії, тому він не представляє собою реального випадку використання для lat / lng.
mkuech

FYI; Mysql підтримує просторовий індекс лише з * .myisam таблицями, тобто двигуном ISAM. Посилання: dev.mysql.com/doc/refman/5.0/uk/creating-spatial-indexes.html
PodTech.io

Перегляньте цю статтю наприкінці оновлення частини: mysqlserverteam.com/mysql-5-7-and-gis-an-example
Джаспал Сінгх

149

Google пропонує почати завершення PHP / MySQL для прикладу програми "Магазин-локатор" на Картах Google. У цьому прикладі вони зберігають значення lat / lng як "Float" довжиною "10,6"

http://code.google.com/apis/maps/articles/phpsqlsearch.html


11
Google чітко не розуміє, як працює специфікація FLOAT: FLOAT(10,6)залишає 4 цифри для цілої частини координати. І ні, знак не рахується - це походить від (не) підписаного атрибута.
Алікс Аксель

2
Але якщо вам потрібно зберегти як цілісні частини значень від [0, 180], то має бути і більше, правда?
Хрвой Голчич

37
@AlixAxel Я думаю, що Google знає, що робить. Тому що в ньому зазначається, що: " При поточних можливостях масштабування на Картах Google вам потрібно лише 6 цифр точності після десяткових знаків. Це дозволить полям зберігати 6 цифр після десяткових знаків плюс до 4 цифр перед десятковою, наприклад - 123,456789 градусів. ". Якщо прапорець непідписаний, шаблон буде 1234,567890 . Тож ніяких проблем.
1,44 Мб

16
@AlixAxel Він відраховує числа в послідовності; не використовуючи фактичну координату ...
Ендрю Елліс

8
Використання типу даних Doubleдля Laravel
FooBar

133

В основному це залежить від точності, яка вам потрібна для ваших місць розташування. Використовуючи DOUBLE, ви отримаєте точність 3,5 нм. ДЕКІМАЛЬНА (8,6) / (9,6) опускається до 16см. ФЛОТ - 1,7 м ...

Ця дуже цікава таблиця має більш повний список: http://mysql.rjweb.org/doc.php/latlng :

Datatype               Bytes            Resolution

Deg*100 (SMALLINT)     4      1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5      1570 m    1.0 mi  Cities
SMALLINT scaled        4       682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6        16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7        16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6       2.7 m    8.8 ft
FLOAT                  8       1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9        16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8        16mm    5/8 in  Marbles
DOUBLE                16       3.5nm     ...    Fleas on a dog

Сподіваюсь, це допомагає.


2
Мені потрібно написати конструктивний, детальний коментар, орієнтований на зміст дописів, тому я скажу, що спостерігаючи за таблицею точності, яку надано на веб-сайті Ріка Джеймса, мене з легкістю розважали в описі резолюції "блохи на собаці" і відчував це гідним кудо. Технічно кажучи, це було корисним зображенням, яке допомогло мені вирішити, який тип даних використовувати при зберіганні координат для вимірювання відстані між двома адресами, що, @Simon, я хотів би подякувати вам за обмін.
Sam_Butler

FWIW, використання цього посилання "SMALLINT масштабується" жахливо неефективне. Відповідь Огужана - чудовий спосіб зберігання довгих / лат із 7 цифрами після десяткової крапки у 4-байтовому підписаному int. Велика точність (~ 1 см) в невеликих розмірах (4В).
ToolmakerSteve

74

Просторові розширення MySQL - найкращий варіант, оскільки у вас є повний перелік просторових операторів та індексів. Просторовий індекс дозволить вам дуже швидко виконувати обчислення на відстані. Будь ласка, майте на увазі, що станом на 6.0 просторове розширення все ще є незавершеним. Я не відкладаю MySQL Spatial, лише повідомляю про підводні камені, перш ніж ви занадто далеко підете на це.

Якщо ви суворо маєте справу з пунктами, і лише функція DISTANCE, це добре. Якщо вам потрібно здійснити будь-які обчислення за допомогою полігонів, ліній або буферних точок, просторові оператори не дають точних результатів, якщо ви не використовуєте оператора "relate". Дивіться попередження вгорі 21.5.6 . Зв'язки, такі як містить, всередині або перетинає, використовують MBR, а не точну геометричну форму (тобто Еліпс трактується як прямокутник).

Також відстані в MySQL Spatial складаються з тих же одиниць, що і ваша перша геометрія. Це означає, що якщо ви використовуєте десяткові градуси, то ваші вимірювання відстані проводяться в десяткових градусах. Це зробить дуже важко отримати точні результати, коли ви отримаєте фуртур від екватора.


26
Перезапуск: Місячні просторові розширення не підходять для обчислення великої відстані кола між точками на поверхні землі, представленими lat / long. Їх дистанційні функції тощо корисні лише на декартових, планарних координатах.
О. Джонс

71

Коли я зробив це для навігаційної бази даних, побудованої з ARINC424, я зробив неабияку кількість тестувань і оглянувшись на код, я використав ДЕКІМАЛЬНИЙ (18,12) (насправді числовий (18,12), тому що це firebird).

Поплавці та парні не такі точні, що може призвести до помилок округлення, що може бути дуже поганою справою. Я не можу пригадати, чи знайшов якісь реальні дані, які мали проблеми - але я впевнений, що неможливість точно зберігати у поплавці або подвійному може спричинити проблеми

Справа в тому, що при використанні градусів або радіанів ми знаємо діапазон значень - і дробова частина потребує найбільших цифр.

В MySQL Просторові розширення є хорошою альтернативою , оскільки вони слідують The OpenGIS Geometry Model . Я не використовував їх, тому що мені потрібно було зберігати свою базу даних.


3
Дякую, це було корисно. Дуже дивно читати всі ці запитання та відповіді з 2008 року, розуміючи, що це вже 8 років тому.
aexl

1
@TheSexiestManinJamaica - До IEEE 754-1985 комп'ютерне обладнання з плаваючою комою було хаотичним. Був навіть на машині, де a*bне було рівних b*a(для деяких значень). Було багато прикладів кілька , як: 2+2 = 3.9999. Стандарт очистив багато безладу, і його «швидко» прийняли практично кожен апаратний та програмний продукт. Отже, ця дискусія є дійсною не лише з 2008 року, а й на третину століття.
Рік Джеймс

42

Залежить від точності, яка вам потрібна.

Datatype           Bytes       resolution
------------------ -----  --------------------------------
Deg*100 (SMALLINT)     4  1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
SMALLINT scaled        4   682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6    16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7    16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6   2.7 m    8.8 ft
FLOAT                  8   1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9    16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8    16mm    5/8 in  Marbles
DOUBLE                16   3.5nm     ...    Fleas on a dog

Від: http://mysql.rjweb.org/doc.php/latlng

Підсумовувати:

  • Найточніший доступний варіант DOUBLE.
  • Найпоширеніший тип, що застосовується, - це DECIMAL(8,6)/(9,6).

Станом на MySQL 5.7 , розгляньте можливість використання типів просторових даних (SDT), спеціально POINTдля зберігання однієї координати. До 5.7 SDT не підтримує індекси (за винятком 5,6, коли тип таблиці - MyISAM).

Примітка:

  • Під час використання POINTкласу має бути порядок аргументів для зберігання координат POINT(latitude, longitude).
  • Існує спеціальний синтаксис для створення просторового індексу .
  • Найбільшою перевагою використання SDT є те, що у вас є доступ до функцій просторового аналізу , наприклад, обчислення відстані між двома точками ( ST_Distance) та визначення того, чи міститься одна точка в іншій області ( ST_Contains).

2
Ви копіюєте вставлену частину попередньої відповіді та "підсумовуєте" те, що хлопець, який створив цю таблицю , не рекомендував : «Як розділити? Ну, MySQL дуже прискіпливий. Тож FLOAT / DOUBLE вийшли. DECIMAL вийшов. Отже, ми застрягли в якійсь хижіні. По суті, нам потрібно перетворити Lat / Lng на деякий розмір INT і використовувати PARTITION BY RANGE. » І «FLOAT має 24 значущі біти; DOUBLE має 53. (Вони не працюють з PARTITIONing, але включені для повноти. Часто люди використовують DOUBLE, не усвідомлюючи, скільки це зайвий вміст і скільки місця займає.) »Просто залиште частину SDT, яку ви написали.
Armfoot

1
@Armfoot Якщо ви подивитесь на час редагувань, це інша відповідь, скопійована у мене. Не те, що це важливо: я бачу, як Stack Overflow більше "нотаток для мене майбутнього".
Gajus

1
Ні, він не копіював від вас, він просто вставив таблицю, як і ви, за посиланням, на яке він посилався у 2014 році (ваше повідомлення - з 2015 року). До речі, я вважаю, що ви неправильно написали "Особливе", коли ви зв'язали типи просторових даних. Ця частина, яку ви написали, насправді корисна людям, які хочуть почати їх використовувати, якщо ви додасте ще кілька прикладів CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;та попередження про обмеження SDT, як згадував Джеймс , можливо, ваша відповідь буде більш лаконічною та точною, допомагаючи і іншим людям. ..
Armfoot

@Gajus - Мені честь, що ви двоє знайшли мій документ! (Ні, я не знаю, наскільки велика блоха, але я відчував, що це приверне чиюсь увагу.)
Рік Джеймс

При використанні класу POINT порядок аргументів для зберігання координат повинен бути POINT (довгота / X, широта / Y).
АндрейП


19

Використовуйте DECIMAL(8,6)для широти (від 90 до -90 градусів) і DECIMAL(9,6)для довготи (від 180 до -180 градусів). Для десятків застосувань - 6 знаків після коми. Обидва повинні бути "підписані", щоб враховувати негативні значення.


DECIMALТип призначений для фінансових розрахунків, коли не floor/ceilприйнято. Рівнина FLOATзначно переважає DECIMAL.
Кондібас

1
@Kondybas - Оскільки основна вартість в базі даних - це отримання рядків, різниця в продуктивності між float і decimal не повинна викликати занепокоєння.
Рік Джеймс

14

За даними Google Maps, не потрібно далеко їхати, найкращим є FLOAT (10,6) для лат і lng.


звідки ви взяли цю інформацію, я не можу її знайти? про всяк випадок, коли щось зміниться.
webfacer

1
@webfacer, це в розділі "Створення таблиці в MySQL" тут: developers.google.com/maps/documentation/javascript/… напр. lat FLOAT( 10, 6 ) NOT NULL, lng FLOAT( 10, 6 ) NOT NULL
turrican_34

1
@webfacer, схоже, що FLOATсинтаксис застарілий станом на mysql 8.0.17. Тепер Mysql рекомендує просто використовувати FLOATбез будь-яких точних параметрів dev.mysql.com/doc/refman/8.0/en/numeric-type-overview.html та dev.mysql.com/doc/refman/5.5/en/floating-point- types.html
turrican_34

7

Ми зберігаємо широту / довготу X 1 000 000 в нашій базі даних oracle як НОМЕРИ, щоб уникнути помилок з округленням.

Враховуючи, що широта / довгота до 6-го десяткового знаку складала 10 см точності, що було все, що нам було потрібно. Багато інших баз даних також зберігають lat / long до 6-го знаку після коми.


2
Множення на деяку велику кількість (наприклад, мільйон) чудово, якщо у вас багато даних, оскільки цілочисельні операції (наприклад, індексований пошук) набагато швидше, ніж плаваючі.
Кейтлін Дак Шервуд

@KaitlinDuckSherwood - біти - це біти - я не знаю жодної причини, коли 32-бітний поплавок був би повільнішим для отримання (індексованим чи іншим способом), ніж 32-бітове ціле число. Навіть плаваюча математика в ці дні є достатньо швидкою, щоб бути проблемою. Тим не менш, я погоджуюся з коментарем щодо використання множника, що мається на увазі, з цілим числом: це забезпечує максимальну точність, яку ви отримуєте з 32 біт. Трохи впевненості в майбутньому, коли технологія вдосконалюється.
ToolmakerSteve

6

У зовсім іншій і простішій перспективі:

  • якщо ви покладаєтесь на Google для показу ваших карт, маркерів, багатокутників, будь-що, тоді нехай розрахунки виконує Google!
  • ви зберігаєте ресурси на своєму сервері і просто зберігаєте широту та довготу разом у вигляді одного рядка ( VARCHAR), наприклад: " -0000.0000001, -0000.000000000000001 " (довжина 35, і якщо число має більше 7 десяткових цифр, воно стає округленим);
  • якщо Google повертає більше 7 десяткових цифр на номер, ви все одно можете отримати ці дані, збережені у вашому рядку, на випадок, якщо ви хочете виявити втечі чи мікроби в майбутньому ;
  • ви можете використовувати їх матрицю відстані або їхню бібліотеку геометрії для обчислення відстаней або виявлення точок у певних областях з викликами настільки просто, як це:google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
  • є безліч API на стороні сервера, якими ви можете користуватися (в Python , Ruby on Rails , PHP , CodeIgniter , Laravel , Yii , Zend Framework тощо), які використовують API Google Maps.

Таким чином, вам не потрібно турбуватися про індексацію чисел та всі інші проблеми, пов’язані з типами даних, які можуть накрутити ваші координати.


Не добре. ОП заявив, що виконуватиме обчислення лат / пара lng - ваші відповіді виключають це
Ярін

4
@Yarin Це популярне питання, де декілька (або багато) людей просто потребують відповіді, як зберігати координати відповідно до власних потреб (велика частина з них може просто використовувати карти Google). Ваш голос говорить про те, що ця відповідь може їм не допомогти ... Зберігаючи координати в рядку, вони точно знатимуть оригінальні значення, які їм було надано (наприклад, від Google), які допоможуть їм пізніше, якщо вони вирішать розвивати свої власний додаток і виконувати обчислення на них. На той час вони все ще матимуть оригінальні необроблені дані лише тому, що вони не зіпсували їх із конверсіями.
Armfoot

4

залежно від вашої програми, я пропоную використовувати FLOAT (9,6)

просторові клавіші нададуть вам більше функцій, але за еталонами виробництва плаваючі плавки набагато швидше, ніж просторові клавіші. (0,01 VS 0,001 в AVG)


1
Чи можете ви надати детальну інформацію про свій тестовий результат тут?
NameNotFoundException

4

MySQL використовує подвійний для всіх плавців ... Тому використовуйте тип double. Використання float призведе до непередбачуваних округлих значень у більшості ситуацій


1
MySQL виконує операції вDOUBLE . MySQL дозволяє зберігати дані як 4-байтові, так FLOATі 8-байтові DOUBLE. Тож, ймовірно, буде втрата точності при зберіганні виразу в FLOATстовпчик.
Рік Джеймс

4

Хоча це не оптимально для всіх операцій, якщо ви робите плиткові карти або працюєте з великою кількістю маркерів (крапок) лише з однією проекцією (наприклад, Меркатор, як очікують Карти Google та багато інших каркасних карток), я знайшов, що Я називаю "Складною системою координат" бути дуже, дуже зручною. В основному ви зберігаєте координати x і y пікселів при деякому збільшенні - я використовую рівень масштабу 23. Це має ряд переваг:

  • Ви робите дорогий lat / lng для перетворення пікселів Меркатора один раз замість кожного разу, коли ви обробляєте точку
  • Отримання координати плитки з запису із заданим рівнем збільшення займає один правий зсув.
  • Отримання координати пікселів із запису займає один правий зсув та один бітовий AND.
  • Зсуви настільки легкі, що практично робити їх у SQL, а це означає, що ви можете виконати DISTINCT, щоб повернути лише один запис на місце пікселя, що зменшить кількість записів, повернених бекендом, що означає меншу обробку на передній кінець.

Я говорив про все це в недавньому дописі в блозі: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/


4

Я дуже здивований деякими відповідями / коментарями.

Чому на землі хтось готовий би добровільно "попередньо зменшити" точність, а потім пізніше виконати обчислення на гірші числа? Звучить в кінцевому рахунку дурно.

Якщо джерело має 64-бітову точність, безумовно, було б глухо добровільно фіксувати масштаб, наприклад. 6 десяткових знаків і обмежте точність максимум на 9 значущих цифр (що відбувається із загально запропонованим десятковим форматом 9.6).

Природно, зберігаються дані з точністю, яку має вихідний матеріал. Єдиною причиною зниження точності буде обмежений простір для зберігання.

  • Зберігайте вихідні фігури з оригінальною точністю
  • Зберігайте цифри, обчислені з джерела, у точності, коли відбувається обчислення (наприклад, якщо в коді заявки використовується подвійне, зберігайте результати як подвійні)

Десятковий формат 9.6 викликає явище оснащення сітки. Це повинен бути самий останній крок, якщо він взагалі відбудеться.

Я б не запрошував накопичені помилки до свого гнізда.


2
Тому що більшість інструментів та програм GPS точні лише до 6 знаків після коми. Безглуздо зберігати дані з більшою точністю, ніж те, якими інструментами можна виміряти gis.stackexchange.com/questions/8650/…
Ярін

1
@ Yarin Так, але ви говорите про вимірювання та GPS, про які не йдеться у питанні. Звичайно, існують більш точні цифри. Але давайте розглянемо GPS; скажімо, набір 64-бітових плаваючих даних джерела даних, який вже містить неточність. 6 десяткових знаків означає прилягання широти до найближчої близько 11 сантиметрів. Отже, лише зберігаючи дані (з 6 десятків) зараз, ви відкриваєте для потенційної неточності 22 см (якщо спочатку теж 11 см). Добровільно, ймовірно, щоб зробити 64-розрядний обчислення на цьому, перш ніж можливо зберігати 3-й раз - зараз 33-сантиметрове вікно неточності, + -16 см. Звучить тупо, імхо.
Stormwind

@ Rick James Я, швидше за все, зберігатимуть його як 64-розрядний, тобто. 0,3333333333333333. Ми говоримо про геодані, правда? "1/3" рідко з'являється в природі, де речі зазвичай вимірюються з розумною точністю.
Stormwind

4

TL; DR

Використовуйте FLOAT (8,5), якщо ви не працюєте в NASA / військових і не створюєте навігаційні системи літаків.


Щоб повністю відповісти на запитання, вам потрібно буде розглянути кілька речей:

Формат

  • градусів хвилин секунди : 40 ° 26 ′ 46 ″ N 79 ° 58 ′ 56 ″ з.д.
  • градусів десяткових хвилин : 40 ° 26,767 ′ N 79 ° 58,933 ′ з.ш.
  • десяткові градуси 1 : 40.446 ° С 79.982 ° З
  • десяткові ступені 2 : -32.60875, 21.27812
  • Якийсь інший домашній формат? Ніхто не забороняє вам створювати власну систему координат, орієнтовану на будинок, і зберігати її як заголовок і відстань від вашого будинку. Це може мати сенс для деяких конкретних проблем, над якими ви працюєте.

Отже, перша частина відповіді була б - ви можете зберігати координати у форматі, який використовує ваша програма, щоб уникнути постійних перетворень вперед і назад та робити більш прості запити SQL.

Найімовірніше, ви використовуєте Карти Google або OSM для відображення своїх даних, а GMaps використовують формат "десяткових градусів 2". Так буде простіше зберігати координати в одному форматі.

Точність

Тоді ви хочете визначити необхідну точність. Звичайно, ви можете зберігати координати на кшталт "-32.608697550570334,21.278081997935146", але коли-небудь ви дбали про міліметри під час навігації до точки? Якщо ви не працюєте в НАСА і не робите супутників, ракет або траєкторій літаків, вам слід погодитися з точністю в кілька метрів.

Найпоширеніший формат - 5 цифр після крапок, що дає точність 50 см.

Приклад : між X, 21.278081 8 та X, 21.278081 9 є відстань 1 см . Таким чином, 7 цифр після крапки дають точність на 1/2 см, а 5 цифр після крапки дадуть точність на 1/2 метра (оскільки мінімальна відстань між окремими точками становить 1 м, тому помилка округлення не може бути більше її половини). Для більшості цивільних цілей цього має бути достатньо.

Формат градусів у десяткових хвилинах (40 ° 26,767 'N 79 ° 58,933 ′ Ш) дає точну точність, як і 5 цифр після крапки

Екологічно ефективне зберігання

Якщо ви вибрали десятковий формат, то ваша координата - пара (-32.60875, 21.27812). Очевидно, що 2 х (1 біт для знака, 2 цифри для градусів і 5 цифр для експонента) буде достатньо.

Тож тут я хотів би підтримати Alix Axel в коментарях, що пропозиція Google зберігати його в FLOAT (10,6) справді зайва, тому що для основної частини вам не потрібно 4 цифри (оскільки знак розділений, а широта обмежена до 90, а довгота обмежена 180). Ви можете легко використовувати FLOAT (8,5) для точності 1/2 м або FLOAT (9,6) для точності 50/2 см. Або ви навіть можете зберігати lat і long у відокремлених типах, тому що FLOAT (7,5) достатньо для lat. Дивіться посилання на поплавкові типи MySQL . Будь-яка з них буде, як звичайний FLOAT, і дорівнює 4 байтам у будь-якому випадку.

Зазвичай простір сьогодні не є проблемою, але якщо ви хочете реально оптимізувати сховище з якихось причин (відмова від відповідальності: не робіть попередньої оптимізації), ви можете стиснути lat (не більше 91 000 значень + знак) + long (ні більше 181 000 значень + знак) до 21 біт, що значно менше 2xFLOAT (8 байт == 64 біта)


3

Просторові функції в PostGIS набагато більш функціональні (тобто не обмежуються операціями BBOX), ніж функції в просторових функціях MySQL. Перевірте це: текст посилання


1
  1. Широта становить від -90 до +90 (градусів), тому ДЕКІМАЛЬНА (10, 8) для цього нормальна

  2. довжина варіюється від -180 до +180 (градусів), тому вам потрібно ДЕКІМАЛЬНИЙ (11, 8).

Примітка: Перше число - це загальна кількість збережених цифр, а друге - число після коми.

Коротко: lat DECIMAL(10, 8) NOT NULL, lng DECIMAL(11, 8) NOT NULL



-2

Обчислення Lat Long вимагають точності, тому використовуйте певний тип десяткового типу і зробіть точність принаймні на 2 вище, ніж число, яке ви будете зберігати, щоб виконати математичні обчислення. Я не знаю про мої типи даних sql, але на SQL-сервері люди часто використовують float або real замість десяткових і потрапляють у проблеми, оскільки це оціночні числа, а не реальні. Тому просто переконайтеся, що тип даних, який ви використовуєте, є істинним десятковим типом, а не плаваючим десятковим типом, і вам повинно бути добре.


1
як поплавкові, так і десяткові типи мають своє місце. як правило, плавці означають фізичні змінні, а десяткові знаки - для рахункових сутностей (переважно грошей). я не бачу, чому ви віддаєте перевагу десятковий для лат / довгий
Хав'єр

1
Я також думаю, що поплавок чудово підходить для лат / довго. Принаймні на SQL Server (4 байти, 7 цифр).
Драголюб Ćurčić

Поплавок не точний, за підрахунками, озеро точності за довгий час є фатальним! Це може вказати на зовсім інше місце на земній кулі.
HLGEM

2
Максимальна помилка плаваючих типів даних є досить низькою, щоб це не було проблемою. Я маю на увазі, у будь-якому випадку ви повинні знати про множення / накопичення помилок з обома реалізаціями.
Spidey

@HLGEM - Округлення до деякої кількості знаків після коми також висаджує вас в інше місце на земній кулі. Питання в тому, чи така різна пляма настільки близька, що не має значення.
Рік Джеймс

-3

A FLOATповинен дати вам всю необхідну точність і бути кращим для порівняльних функцій, ніж зберігати кожну координату у вигляді рядка чи подібного.

Якщо ваша версія MySQL раніше, ніж 5.0.3, можливо, вам потрібно буде прислухатися до певних помилок порівняння з плаваючою комою .

До MySQL 5.0.3, стовпці DECIMAL зберігають значення з точною точністю, оскільки вони представлені у вигляді рядків, але обчислення значень DECIMAL проводяться за допомогою операцій з плаваючою комою. Станом на 5.0.3, MySQL виконує операції DECIMAL з точністю до 64 десяткових цифр, що повинно вирішити найпоширеніші проблеми з неточністю, якщо мова йде про стовпці DECIMAL


2
Вам потрібен реальний тип даних координат широти / довготи для легкої математики. Уявіть зручність чогось подібного до "вибору * з магазинів, де відстань (магазини.локація, мілокація) <5 миль"
Кірк Штраузер

1
Якщо ви раніше не чули про просторові розширення, це звучить дуже зручно, попередньо працюючи над успадкованим додатком, який робить зовсім небагато обчислень, пов’язаних з географією, повинен перевірити це.
ConroyP

@ConroyP - Ні. Ця цитата вказує на те, що DECIMALбули (раніше 5.0.3) певні помилки через використання плаваючої реалізації.
Рік Джеймс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.