순서
- 거리 계산 하기
- 하버사인 공식
- MySQL 하버사인 공식 적용 (내용이 궁금하지 않으면, 바로 3번으로!)
1. 거리 계산하기
사실 이 내용에 대해서는 상당히 많은 부분의 설명이 필요하다.
- 위도와 경도가 무엇인지 알아야 하며,
- 지구의 반지름에 대해서도 알아야 하고..
- sin, cos에 대해서도 알아야 한다.
상당히 많은 부분을 알아야 하므로 이 부분에 대해서 간단히 넘어가려 한다.
(그래도 궁금한 건 못 참는다 하시는 분들은 여기를 참조하세요.)
2-D ( x-y ) 좌표에서 두 점 사이의 거리를 게산해 본 적이 있다면, 기억을 더듬어서 어떻게 했는지 기억해보자.
A(3, 9)
B(6, 13)
위도-경도로 표시된 좌표도 두 점 사이의 거리를 구하는 것처럼,
- 두 점간의 위도 차이
- 두 점간의 경도 차이
의 합에 루트(2)를 씌우면 된다.
그러면 두 점 사이의 거리가 나온다.
하지만 여기서 우리는 간과한 게 하나 있다. 바로 저 두 점 사이의 거리는 사실 "최단"거리이다.
무슨 말이냐 하면, 호의 길이를 구한 게 아니라 현의 길이를 구했다는 얘기이다.
현과 호가 무엇인지는 여기를 보면 알 수 있다. (여기!)
2. 하버사인 공식
그럼 구의 형태인 지구에서 두 지점 사이의 거리는 어떻게 구할까?
바로 하버 사인 공식을 활용하면 된다. (Haversine Formula)
하버 사인에 대해서는 궁금한 사람은 링크로 들어가서 확인해보길 바란다. (영어..)
하버사인 공식은 이렇다 (해당 웹사이트에 나와있는 걸 보면, 공식, 자바스크립트, 엑셀로 다 정리되어있다)
그렇다면 허버사인 공식을 MySQL 식으로 바꾸면?
3. MySQL 하버사인 공식 적용
-- KM : 6371
-- MILES : 3959
SELECT
(
6371 * acos (
cos ( radians(source_lat) )
* cos( radians( lat ) )
* cos( radians( lng ) - radians(source_lon) )
+ sin ( radians(source_lat) )
* sin( radians( lat ) )
)
) AS distance
FROM some_geo_locations;
위에 나와있는 것 처럼 cos, sin, acos, radians 를 사용하여 나타낼 수 있다.
그렇다면 예시로, 우리가 흔하게 사용하는 내 주변검색 등의 기능을 위의 MySQL 계산을 활용하여 찾아보자.
-- KM : 6371
-- MILES : 3959
SELECT
id, (
6371 * acos (
cos ( radians(source_lat) )
* cos( radians( lat ) )
* cos( radians( lng ) - radians(source_lon) )
+ sin ( radians(source_lat) )
* sin( radians( lat ) )
)
) AS distance
FROM toilets
HAVING distance < 2
ORDER BY distance
LIMIT 0 , 20;
위의 공식은 toilets 이라는 table 에서 2km 반경의 toilet 을 검색한 것이다. HAVING 을 사용하여 distance 를 2km 내로 필터링 하였으며, distance 로 ORDERING 하여, 가까운 toilet 을 먼저 보여주게 Query 가 작성됨을 알 수 있다.
References:
m.blog.naver.com/jinohpark79/221170630625
www.movable-type.co.uk/scripts/latlong.html?from=48.619,-120.412&to=48.59617,-120.4020
'IT Study > 데이터베이스' 카테고리의 다른 글
MySQL 운영 노하우(Know-how) II - DATA TYPE 알고 쓰자! (2) | 2023.07.18 |
---|---|
MySQL 운영 노하우(Know-how) I (0) | 2023.07.16 |
MYSQL 쿼리 튜닝(2) - EXPLAIN (0) | 2020.11.01 |
MySQL 쿼리 튜닝 은 어떻게 할까? 기초편 (INDEX) (0) | 2020.10.31 |