從 MySql 5.7 更新到 8.0 後空間查詢的數據截斷
我有下表:
create table places ( id bigint auto_increment primary key, position point SRID 4326 not null ); create spatial index position on places (position); -- Some test data insert into places (position) values (st_srid(POINT(40.67 -73.94))), (st_srid(POINT(38.895 -77.036666666))), (st_srid(POINT(37.7775 -122.416388888))), (st_srid(POINT(52.516666666 13.383333333))), (st_srid(POINT(34.05223 -118.24368))), (st_srid(POINT(46.94798 7.44743))), (st_srid(POINT(46.2 6.15))), (st_srid(POINT(47.378611111 8.54))), (st_srid(POINT(47.560555555 7.590555555)));
在 MySql 8.0 數據庫上。數據是從 5.7 數據庫導入的(5.7 數據庫
position
列的每一行的 SRID 也設置為 4326)。我知道從 5.7 到 8.0,SRID 4326 的幾何對像上的 X 和 Y 被交換了,所以這些點現在是“緯度,經度”,所以當我導入我應用的數據
ST_SwapXY()
時position
。(請注意,我還在未執行此步驟的相同表上嘗試了以下查詢。)當我嘗試執行類似於以下內容的查詢時:
SET @lon = 7.4653; SET @lat = 51.5136; SELECT p.id, ST_Distance_Sphere(p.position, ST_SRID(POINT(@lat, @lon), 4326)) AS distance, ST_AsText(p.position) FROM ( SELECT id, position FROM places WHERE MBRContains(ST_GeomFromText(CONCAT('Polygon((', @lat -3.0, ' ', @lon -3.0, ', ', @lat +3.0, ' ', @lon -3.0, ', ', @lat +3.0, ' ', @lon +3.0, ', ', @lat -3.0, ' ', @lon +3.0, ', ', @lat -3.0, ' ', @lon -3.0, '))'), 4326), position) OR position = ST_SRID(POINT(0.0, 0.0), 4326) LIMIT 10000 ) p ORDER BY distance LIMIT 10;
我收到以下錯誤:
[22001][3732] Data truncation: A parameter of function mbrcontains contains a geometry with latitude -122.416389, which is out of range. It must be within [-90.000000, 90.000000].
如果我在通話中將所有
@lat
s 與s 交換,也會發生這種情況。@lon``MBRContains()
我是否錯過了導入數據時應該採取的其他步驟?有什麼我沒有考慮的嗎?如何使查詢工作?
我發現了問題。
MySQL 8.0 倒置經緯度時,並沒有倒置幾何本身的結構,而只是倒置了空間函式中的表示。
我想這些資訊可以在文件的某個地方找到,但我個人無法找到任何明確說明從 5.7 到 8.0 的更改只影響空間功能和點的文本表示,而不是點本身的內容。幹得好,甲骨文。:/
所以簡而言之,解決方案是簡單地使用一個不交換 x 和 y 的表,而是在查詢中的任何地方交換 x 和 y。
**編輯:**此外,
distance
查詢的列使用 order 產生不正確的結果POINT(@lat, @lon)
。使用 會產生正確的結果POINT(@lon, @lat)
,這意味著定義點時必須不考慮經緯度的反演,除非定義通過ST_
orMBR
函式。