Sự khác biệt giữa POINT (X, Y) và GeomFromText (ĐIỂM ĐIỂM (XY)) là gì?


17

Tôi muốn lưu trữ một số vị trí hình học trong cơ sở dữ liệu MySQL của tôi. Đối với điều này, tôi sử dụng kiểu dữ liệu POINT. Hầu như ở mọi nơi tôi đọc rằng hàm GeomFromTextnày nên được sử dụng để chèn dữ liệu vào bảng.

Tuy nhiên, tôi phát hiện ra rằng POINT(X,Y)cũng hoạt động. Tôi đã không tìm thấy bất kỳ mô tả tại sao GeomFromTextnên được sử dụng thay vì POINT.

Ví dụ tôi có quan hệ đơn giản sau:

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

Và tôi có thể chèn giá trị bằng hai biến thể sau:

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

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

Khi tôi xem bảng ( SELECT * FROM Site) tôi thấy cùng một đốm nhị phân cho vị trí và khi tôi xem tọa độ ( SELECT *, AsText(Position) FROM Site) tôi cũng thấy các giá trị tương tự.

Vậy tại sao GeomFromText nên được sử dụng? Có sự khác biệt nào về hiệu suất (đã biết) giữa hai biến thể này không? Làm thế nào điều này được giải quyết trong các hệ thống cơ sở dữ liệu khác ngoài MySQL?


Tôi không biết có sự khác biệt nào về hiệu suất không (tôi đoán là không nhưng đó chỉ là phỏng đoán). Nhưng cách tiếp cận thứ hai sẽ đơn giản hơn khi chuyển đổi các giá trị vĩ độ và kinh độ từ một bảng khác. INSERT INTO Site (Position) SELECT POINT(latitude, longitude) FROM tmpđơn giản hơn...SELECT GeomFromText(CONCAT('POINT(',latitude,' ',longitude,')' )) ...
ypercubeᵀᴹ

Tôi cũng tìm thấy biến thể thứ hai đơn giản hơn nhiều để xây dựng, đó là lý do tại sao tôi tự hỏi rằng thường thì biến thể thứ nhất được sử dụng ở hầu hết mọi nơi mà tôi thấy các phần mở rộng không gian của MySQL được sử dụng.
ComSubVie

Tôi vừa thử chèn 10.000.000 vị trí trong bảng trên (trên máy chủ của tôi) bằng cả hai biến thể và không phát hiện thấy bất kỳ sự khác biệt hiệu suất có thể đo lường nào.
ComSubVie

Vui lòng xem xét đánh giá lại điều này dưới ánh sáng của MySQL 8+ và cho hậu thế: dba.stackexchange.com/a/227049/2639
Evan Carroll

Câu trả lời:


16

Có hai định dạng nhị phân khác nhau liên quan đến các phần mở rộng không gian của MySQL, định dạng "nhị phân nổi tiếng" (WKB) từ các tiêu chuẩn và GEOMETRYloại dữ liệu nội bộ của MySQL .

Trước MySQL 5.1.35, các chức năng như POINT()không trả về kiểu dữ liệu nội bộ của MySQL; họ đã trả lại WKB ... vì vậy trước đó, bạn phải làm điều này:

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

Nhưng bây giờ, như trong ví dụ của bạn, điều này hoạt động:

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

Đối với tín dụng của các nhà phát triển, khi họ thay đổi Point()và các chức năng tương tự với GEOMETRYcác đối tượng trả lại (hoàn toàn hơn) , họ đã cho phép GeomFromWKB()và các chức năng tương tự thực sự chấp nhận dữ liệu Hình học WKB hoặc MySQL làm đầu vào mặc dù các chức năng dự định chấp nhận WKB làm đầu vào.

Thực tế là phương thức 1 hoạt động (mặc dù sai về mặt kỹ thuật) trên các máy chủ mới hơn và phương thức thứ 2 hoàn toàn không hoạt động trước MySQL 5.1.35 có thể giải thích tại sao các ví dụ được viết bằng cách sử dụng phương pháp bạn đã thấy - tránh vấn đề hoàn toàn Nếu không ... tôi không có gì ở đây.

Ghép nối và sau đó phân tích văn bản có vẻ chậm hơn và dễ bị lỗi hơn các hàm chấp nhận các biến thích hợp làm đầu vào, vì vậy tôi không thể nghĩ ra bất kỳ lý do nào để tạo các chuỗi nối và sử dụng các hàm dựa trên văn bản.

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

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


1
Cảm ơn, thật thú vị khi điều này chỉ được đề cập như một "chú thích" trong ghi chú phát hành và không có trong tài liệu này. Vì vậy, tôi sẽ tránh xa các phương pháp dựa trên văn bản.
ComSubVie

1
Tại sao 5 năm sau, các tài liệu MySQL vẫn đưa ra các ví dụ về việc sử dụng hàm ST_GeomFromText () khi chèn? Câu trả lời này có còn phù hợp không? Hơi khó hiểu một chút .. dev.mysql.com/doc/refman/5.7/en/population-spatial-columns.html
Matt Kieran

1
@MattKieran WKB và WKT là các định dạng mở, được chuẩn hóa để thể hiện dữ liệu không gian địa lý. Các ví dụ sử dụng chúng vì các ứng dụng không gian địa lý theo tiêu chuẩn có thể đã giữ dữ liệu ở các định dạng này, cho phép MySQL chấp nhận hình học bên ngoài như một đối số duy nhất ST_GeomFromText()và các hàm chuyển đổi tương tự thay vì yêu cầu các ứng dụng bên ngoài sử dụng các hàm SQL gốc xây dựng các đối tượng hình học, được tìm thấy trong Tài liệu tham khảo chức năng không gian . Các tài liệu có thể được tổ chức tốt hơn.
Michael - sqlbot

Ngoài ra @MattKieran câu trả lời này vẫn chỉ phù hợp theo nghĩa nó giải thích tại sao các ví dụ cũ hơn có thể được viết trái với những gì các tài liệu chỉ ra, bất kỳ lý do nào mà MySQL hoạt động với kiểu không khớp rõ ràng mà sử dụng các hàm theo cách này dường như chỉ ra. Tất cả ba phương thức - các hàm SQL gốc, WKB (nhị phân) hoặc WKT (văn bản) - đều hợp lệ. Điều không cần thiết nữa là hội tụ các giá trị trả về của hàm gốc từ WKB, bởi vì các kiểu trả về của chúng không còn là WKB như nhiều năm trước.
Michael - sqlbot

4

MySQL 8+

Đối với hậu thế, điều duy nhất quan trọng

  • Point(X,Y)là một hàm tạo cho các số có độ chính xác và không yêu cầu chuyển đổi trước thành văn bản làm cho nó nhanh hơn. Nó cũng được đảm bảo để TRẢ LẠI POINTHOẶC FAIL . Điều này làm cho nó gõ mạnh nếu bạn muốn nghĩ về nó như thế.
  • Các nhà xây dựng văn bản được biết đến (WKT) : chúng luôn chậm hơn, vì chúng yêu cầu một bước bổ sung để phân tích văn bản được biết đến (WKT) . Lưu ý trong các phiên bản cũ hơn, chúng có thể được tìm thấy mà không có ST_tiền tố; nếu có sẵn, sử dụng phiên bản có ST_tiền tố. Chỉ sử dụng các hàm tạo WKT nếu đầu vào của bạn đã là văn bản nổi tiếng. Nếu không, sử dụng hàm Point(x,y)tạo ở trên.
    • ST_GeomFromText(wkt, srid)có thể trả về BẤT K type loại không gian nào được hỗ trợ bởi MySQL và có thể được đại diện bởi WKT. Điều này làm cho nó đượclỏng lẻo nếu bạn muốn nghĩ về nó như thế.
    • ST_PointFromText(wkt, srid)một nhà POINTxây dựng đánh máy mạnh mẽ từ văn bản nổi tiếng.

Trong trẻo

Bỏ qua bài học lịch sử, KHÔNG BAO GIỜ làm GeomFromText(Point(x,y)). Điều đó thật kinh khủng, không được hỗ trợ và không có giấy tờ.


-1

Với GeomFromText hoặc bất kỳ chức năng * FromText nào khác, bạn có thể chỉ định SRID . Tôi không nghĩ bạn có thể làm điều đó khác.

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

Điều này sẽ là cách khác xung quanh tức là POINT(lng lat)thay vìPOINT(lat lng)
Zishan

Dù sao thì MySQL cũng không sử dụng SRID. Vì vậy, nó khá vô dụng. Nếu bạn cần SRID, hãy di chuyển sang PostgreSQL / PostGIS.
Evan Carroll

1
MySQL 8 không sử dụng SRID. Trên thực tế, tôi gặp sự cố với MySQL DB di chuyển chính xác từ 5,7 đến 8 do SRID.
cmoran92
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.