Яка різниця між POINT (X, Y) та GeomFromText ("POINT (XY)")?


17

Я хотів би зберегти деякі геометричні положення у моїй базі даних MySQL. Для цього я використовую тип даних POINT. Майже скрізь я читав, що функціяGeomFromText слід використовувати для вставки даних у таблицю.

Однак я з’ясував, що POINT(X,Y)також працює. Я не знайшов жодного опису, чому його GeomFromTextслід використовувати замість POINT.

Наприклад, у мене таке просте відношення:

CREATE TABLE Site (
    SiteID      BIGINT UNSIGNED,
    Position    POINT
);

І я можу вставити значення, використовуючи наступні два варіанти:

INSERT INTO Site (
    1,
    GeomFromText( 'POINT(48.19976 16.45572)' )
);

INSERT INTO Site (
    2,
    POINT(48.19976, 16.45572)
);

Коли я переглядаю таблицю ( SELECT * FROM Site), я бачу ту саму бінарну крапку для розташування, а коли я переглядаю координати ( SELECT *, AsText(Position) FROM Site), я також бачу однакові значення.

То навіщо використовувати GeomFromText? Чи існують (відомі) відмінності в роботі між цими двома варіантами? Як це вирішується в інших системах баз даних, крім MySQL?


Я не знаю, чи є якісь відмінності в роботі (я б не здогадувався, але це лише здогадки). Але другий підхід був би простішим при перетворенні значень широти і довготи з іншої таблиці. INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmpпростіше, ніж...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
ypercubeᵀᴹ

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

Я просто спробував вставити 10 000 000 місць у таблицю вище (на своєму хості), використовуючи обидва варіанти, і не виявив жодної вимірюваної різниці в продуктивності.
ComSubVie

Будь ласка, подумайте про повторну оцінку цього з урахуванням MySQL 8+ та нащадків: dba.stackexchange.com/a/227049/2639
Еван Керролл

Відповіді:


16

Існує два різні бінарні формати, пов'язані з просторовими розширеннями MySQL, "добре відомим бінарним" (WKB) форматом зі стандартів та внутрішнім GEOMETRYтипом даних MySQL .

До MySQL 5.1.35 такі функції, як, наприклад POINT(), не повернули внутрішній тип даних MySQL; вони повернули WKB ... так що раніше, ви повинні були зробити це:

INSERT INTO t1 (pt_col) VALUES (GeomFromWKB(Point(1,2)));

Але тепер, як у вашому прикладі, це працює:

INSERT INTO t1 (pt_col) VALUES(Point(1,2));

На Point()відміну від розробників, коли вони змінили і подібні функції (більш розумно) повертали GEOMETRYоб'єкти, вони дозволили GeomFromWKB()подібним функціям фактично приймати дані WKB або MySQL Geometry як вхідні дані, навіть якщо функції призначені приймати WKB як вхідні дані.

Той факт, що 1-й метод працює (незважаючи на технічну помилку) на новіших серверах, а другий метод взагалі не працює до MySQL 5.1.35, може пояснити, чому приклади були написані з використанням підходу, який ви бачили - уникайте проблеми цілком. Інакше ... тут я нічого не маю.

З'єднання та розбір тексту здається інтуїтивно повільнішим і більш схильним до помилок, ніж функції, які приймають власні змінні в якості вхідних даних, тому я не можу придумати жодної причини для створення об'єднаних рядків та використання текстових функцій.

http://dev.mysql.com/doc/refman/5.1/uk/creating-spatial-values.html#gis-wkb-functions

http://dev.mysql.com/doc/relnotes/mysql/5.1/uk/news-5-1-35.html


1
Дякую, цікаво, що це згадується лише як «виноска» у примітках до випуску і ніде в документації. Тож я буду триматися подалі від текстових методів.
ComSubVie

1
Чому через 5 років документи MySQL все ще наводять приклади використання функції ST_GeomFromText () при вставці? Ця відповідь все ще актуальна? Це трохи заплутано .. dev.mysql.com/doc/refman/5.7/uk/populating-spatial-column.html
Метт Кіран

1
@MattKieran WKB і WKT є стандартизованими, відкритими форматами для вираження геопросторових даних. Приклади використовують їх, оскільки геопросторові програми, орієнтовані на стандарти, вже можуть зберігати дані в цих форматах, що дозволяє MySQL приймати зовнішні геометрії як єдиний аргумент ST_GeomFromText()та подібні функції перетворення, а не вимагати від зовнішніх додатків використання вбудованих функцій SQL, які будують геометричні об'єкти, які містяться в Довіднику про просторові функції . Документи можна було б краще організувати.
Майкл - sqlbot

Також @MattKieran ця відповідь залишається актуальною лише в тому сенсі, що вона пояснює, чому старі приклади можуть бути написані всупереч тому, що вказують документи, і будь-чому, чому MySQL працює з явними невідповідностями типу, які, мабуть, вказують на використання функцій. Усі три методи - нативні функції SQL, WKB (двійкові) або WKT (текст) - дійсні. Що більше не потрібно, це перетворення нативних функцій повернення значень з WKB, тому що їхні типи повернення вже не є WKB, як це було багато років тому.
Майкл - sqlbot

4

MySQL 8+

Для нащадків важливо лише це

  • Point(X,Y)є конструктором для чисел з точністю і не потребує перетворення спочатку в текст, що робить його швидшим. Це також гарантує повертають POINTабо зазнати невдачі . Це робить його сильно набраним, якщо ви хочете думати про це так.
  • Добре відомі конструктори тексту (WKT) : вони завжди повільніші, оскільки вони потребують додаткового кроку для розбору добре відомого тексту (WKT) . Зауважте, що у старих версіях їх можна знайти без ST_префікса; якщо є, використовуйте версію з ST_префіксом. Використовуйте WKT-конструктори лише у тому випадку, якщо ваш текст уже відомий текст. Якщо ні, використовуйте Point(x,y)конструктор вище.
    • ST_GeomFromText(wkt, srid)може повернути будь-який просторовий тип, який підтримується MySQL і може бути представлений WKT. Це робить його вільно надрукував , якщо ви хочете , щоб думати про нього , як це.
    • ST_PointFromText(wkt, srid)сильно набраний POINT-конструктор з добре відомого тексту.

Чіткість

Пропускаючи урок історії, НІКОЛИ не робіть GeomFromText(Point(x,y)). Це жахливо, непідтримувано та бездокументовано.


-1

За допомогою GeomFromText або будь-якої іншої функції * FromText ви можете вказати SRID . Я не думаю, що ти можеш це зробити інакше.

PointFromText('POINT(lat lng)', 4326)

Це має бути навпаки, POINT(lng lat)а неPOINT(lat lng)
Зішан

MySQL так і не використовує SRID. Тож це досить марно. Якщо вам потрібні SRID, перейдіть до PostgreSQL / PostGIS.
Еван Керролл

1
MySQL 8 використовує SRID. Насправді у мене виникають проблеми з тим, що мій БД MySQL перемістився з 5,7 до 8 саме через SRID.
cmoran92
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.