筆記:MySQL Spatial Extensions

來源:互聯網
上載者:User

最好的Spatial Database(空間資料庫)當然是Oracle家的,可惜沒用過。最好的開源的Spatial Database一般公認是PostGIS,以前用過一陣子,安裝特別麻煩,不過各種功能很齊全。前段時間嘗試了一下MySQL的spatial extensions,下面記錄了一些使用心得:

1. MySQL Spatial Extensions(後面簡稱MySQL Spatial)功能不夠完全。至少和PostGIS相比是這樣的,它只支援了openGIS(一個標準)的一個子集,包涵有限的幾種空間資料類型(比如Point,LineString,Polygon等),支援的函數也很少,比如,連計算兩個點的distance函數都沒有...

2. MySQL Spatial的安裝配置非常的簡單。其實,它根本不需要安裝。預設的MySQL配置就能夠使用這些空間資料類型。這和PostGIS很不一樣,PostGIS是需要在PostgreSQL上再安裝一個擴充包。

3. 不同的儲存引擎有差別。MyISAM和InnoDB都支援spatial extensions,但差別在於:如果使用MyISAM,可以建立spatial index,而InnoDB是不支援的。這點差別在某些情境下很關鍵,後面會再詳細說說spatial index。

4. POINT的使用。點是最基本也是最常用的一種空間資料類型。MySQL Spatial中用POINT表示點,比如,可以建立一個table:

CREATE TABLE address (

  address CHAR(80) NOT NULL,

  address_loc POINT NOT NULL,

  PRIMARY KEY(address),

  SPATIAL KEY(address_loc)

);

其中,address_loc就是一個point類型,說明address_loc是一個點。

插入一個點:

INSERT INTO address VALUES('Foobar street 12', GeomFromText('POINT(2671 2500)'));

讀取一個點:

select  AsText(address_loc)  from address …

一個比較麻煩的問題是,如何計算兩個POINT的距離?之前說過了,MySQL Spatial不提供distance這個函數。官方指南的做法是這樣的:

GLength(LineStringFromWKB(LineString(point1, point2)))

這條語句大概的意思是用兩個點產生一個LineString的類型,然後調用GLength得到line的長度。

這麼做,也對也不對。

對是因為它確實計算的是距離,但是,這種方法計算的是歐式空間的距離。或者簡單的說,它計算的是直線距離。如果兩個點是地理座標,比如point(116.34, 39.28),想計算地理位置的距離,那麼這樣做肯定就不對了。正確的做法應該是使用專門計算地理位置的公式。

 

5. MySQL Spatial Index的使用。使用這樣的語句:
ALTER TABLE address ADD SPATIAL INDEX(address_loc);

可以在空間資料類型上建立一個spatial index,這個功能只有MyISAM才支援。Index的本質實際上是一個R-TREE,這也是最常用來作為多維資料索引的資料結構。

那麼,該如何使用這個index?

舉例來說,假設需要尋找某個矩形地區內所有的點,一種方法是這樣:
select * from address where (X(address_loc) > 116.3952) AND (X(address_loc) < 116.4052) AND (Y(address_loc) > 39.8603) AND (Y(address_loc) < 39.8703);

假設我們已經在address_loc這個column上建立了spatial index,所以上述的查詢應該很快。不幸的是,這不是事實。上述的查詢會掃描table內的所有資料,挨個進行計算,建立的index完全不起作用。

正確的做法是,在查詢中使用一些內建的和spatial有關的函數,只有這些函數能夠有效利用到index。比如,正確的查詢應該是:
select AsText(address_loc) from address where MBRContains(GeomFromText(Polygon((115.3073 40.3821, 115.3173 40.3821, 115.3173 40.4021, 115.3073 40.4021, 115.3073 40.3821))),address_loc);

這裡用到了函數MBRContains,用於判斷一個point是否在指定的polygon內部。這個函數就能夠很好的使用之前建立的spatial index。可以做個實驗,比較之前兩個查詢的處理時間,你會發現,後者的速度要快很多。

 

總的來說,如果只需要做一些簡單的GIS或者LBS的應用,MySQL提供的spatial extensions能夠滿足。但如果需要的功能更複雜一些,MySQL spatial extensions提供的功能可能就不夠用了,需要在MySQL之上自己實現更多的邏輯,或者換成PostGIS。

 

Reference:

【1】官方文檔: http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html

【2】官方文檔: http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.