อะไรคือความแตกต่างระหว่าง POINT (X, Y) และ GeomFromText (“ POINT (XY)”)


17

ฉันต้องการจัดเก็บตำแหน่งทางเรขาคณิตบางอย่างในฐานข้อมูล MySQL ของฉัน สำหรับสิ่งนี้ฉันใช้ประเภทข้อมูล POINT เกือบทุกที่ฉันอ่านว่าGeomFromTextควรใช้ฟังก์ชั่นเพื่อแทรกข้อมูลลงในตาราง

อย่างไรก็ตามฉันพบว่าPOINT(X,Y)ยังใช้งานได้ ฉันไม่พบคำอธิบายว่าทำไมควรจะนำมาใช้แทนGeomFromTextPOINT

ตัวอย่างเช่นฉันมีความสัมพันธ์แบบง่าย ๆ ดังต่อไปนี้:

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
Evan Carroll

คำตอบ:


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 data เป็นอินพุตแม้ว่าฟังก์ชันนั้นตั้งใจจะยอมรับ 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


1
ขอขอบคุณที่น่าสนใจว่านี่เป็นเพียง "เชิงอรรถ" ในบันทึกย่อประจำรุ่นและไม่มีในเอกสารประกอบ ดังนั้นฉันจะอยู่ห่างจากวิธีการใช้ข้อความ
ComSubVie

1
ทำไม 5 ปีต่อมาเอกสาร MySQL ยังคงให้ตัวอย่างการใช้ฟังก์ชัน ST_GeomFromText () เมื่อทำการแทรก? คำตอบนี้ยังเกี่ยวข้องหรือไม่ มันค่อนข้างสับสน .. dev.mysql.com/doc/refman/5.7/en/populating-spatial-columns.html
Matt Kieran

1
@MattKieran WKB และ WKT เป็นมาตรฐานเปิดรูปแบบสำหรับการแสดงข้อมูลเชิงพื้นที่ ตัวอย่างใช้พวกมันเพราะแอพพลิเคชั่นเชิงพื้นที่เชิงมาตรฐานอาจเก็บข้อมูลในรูปแบบเหล่านี้แล้วทำให้ MySQL สามารถยอมรับรูปทรงเรขาคณิตภายนอกเป็นอาร์กิวเมนต์เดียวST_GeomFromText()และฟังก์ชั่นการแปลงที่คล้ายกันแทนที่จะต้องใช้แอพพลิเคชั่นภายนอก ที่พบในการอ้างอิงฟังก์ชั่นเชิงพื้นที่ เอกสารสามารถจัดระเบียบได้ดีขึ้น
Michael - sqlbot

@MattKieran @ คำตอบนี้ยังคงเกี่ยวข้องเฉพาะในแง่ที่อธิบายว่าทำไมตัวอย่างเก่า ๆ อาจถูกเขียนตรงข้ามกับสิ่งที่เอกสารระบุว่าทำไม MySQL ทำงานกับชนิดที่ไม่ตรงกันซึ่งการใช้ฟังก์ชั่นแบบนี้ดูเหมือนจะบ่งบอก ทั้งสามวิธี - ฟังก์ชัน SQL ดั้งเดิม, WKB (ไบนารี) หรือ WKT (ข้อความ) - ถูกต้อง สิ่งที่ไม่ต้องการอีกต่อไปคือการแปลงค่าที่ส่งคืนของฟังก์ชันเนทีฟจาก WKB เนื่องจากประเภทที่ส่งคืนของพวกเขาจะไม่ WKB อีกต่อไปเหมือนเมื่อหลายปีก่อน
Michael - 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)
Zishan

MySQL ไม่ได้ใช้ SRID ดังนั้นมันจึงไร้ประโยชน์ หากคุณต้องการ SRID ให้ย้ายไปที่ PostgreSQL / PostGIS
Evan Carroll

1
MySQL 8 ใช้ SRID ที่จริงแล้วฉันมีปัญหากับฐานข้อมูล MySQL ที่ย้ายจาก 5.7 ไปเป็น 8 อย่างแม่นยำเนื่องจาก SRID
cmoran92
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.