В чем разница между 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?

ComSubVie
источник
Я не знаю, есть ли различия в производительности (думаю, нет, но это только предположение). Но второй подход будет проще при преобразовании значений широты и долготы из другой таблицы. 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-й метод работает (несмотря на техническую ошибку) на более новых серверах, а 2-й метод вообще не работает до MySQL 5.1.35, может объяснить, почему примеры были написаны с использованием подхода, который вы видели - полностью избежать проблемы. В противном случае ... у меня ничего нет, здесь.

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

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

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

Майкл - sqlbot
источник
1
Спасибо, интересно, что это упоминается только как «сноска» в примечаниях к выпуску и нигде в документации. Поэтому я буду держаться подальше от текстовых методов.
ComSubVie
1
Почему 5 лет спустя документы MySQL по-прежнему дают примеры использования функции ST_GeomFromText () при вставке? Этот ответ по-прежнему актуален? Это немного сбивает с толку .. dev.mysql.com/doc/refman/5.7/en/population-spatial-columns.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)
fromvega
источник
Это должно быть наоборот, то есть POINT(lng lat)вместоPOINT(lat lng)
Zishan
MySQL в любом случае не использует SRID. Так что это довольно бесполезно. Если вам нужны SRID, перейдите на PostgreSQL / PostGIS.
Эван Кэрролл
1
MySQL 8 использует SRID. На самом деле, у меня проблемы с БД MySQL, перенесенной с 5.7 на 8 именно из-за SRID.
cmoran92