우아한테크코스 테코톡

율무의 MySQL로 알아보는 공간 데이터

https://youtu.be/J-4-vQOHaBI?si=3iGAszwby8Jt_es7

율무의 MySQL로 알아보는 공간 데이터


MySQL로 공간 데이터를 다루는 방법: 좌표를 넘어서 점, 선, 면까지

지도 서비스, 배달 가능 지역 판별, 러닝 코스 추천, 근처 매장 탐색 같은 기능은 모두 “공간 데이터”를 다루는 문제다. 발표 자료에서도 포켓몬고, 네이버 지도, 당근, 런세권 같은 서비스가 예시로 등장하고, 많은 기업이 이미 공간 데이터 활용을 중요한 기술 주제로 다루고 있다고 설명한다.

그런데 실무에서는 여전히 위도와 경도를 일반 DOUBLE 컬럼 두 개로 저장하고, 복잡한 수식을 직접 SQL에 넣어 처리하는 경우가 많다. 이 방식도 가능은 하지만, 표현력이 떨어지고 쿼리가 복잡해지며, 공간 연산의 의도를 SQL만 봐서는 파악하기 어려워진다. MySQL의 공간 데이터 타입과 공간 함수를 활용하면 이런 문제를 훨씬 더 직관적이고 효율적으로 해결할 수 있다. 발표 자료도 일반 컬럼 방식보다 공간 데이터 방식이 쿼리를 훨씬 쉽게 작성할 수 있다고 강조한다.

공간 데이터란 무엇인가

공간 데이터는 말 그대로 “장소를 표현하는 데이터”다. 자료에서는 공간을 “어떤 물질이나 물체가 존재할 수 있거나 어떤 일이 일어날 수 있는 장소”라고 설명하고, 그 장소를 표현하는 데이터가 곧 공간 데이터라고 정리한다.

여기서 중요한 포인트는 장소의 이름, 면적, 건물 용도 같은 값들은 공간 그 자체라기보다 속성 데이터에 가깝다는 점이다. 공간 데이터의 핵심은 결국 좌표다. 그리고 이 좌표는 단순히 X, Y 한 점으로 끝나지 않는다. 실제 서비스에서는 길처럼 이 필요하고, 행정구역이나 배달 가능 지역처럼 도 필요하다. 발표 자료도 “한 점만으로는 모든 공간을 표현하기 어렵기 때문에 선과 면도 함께 표현해야 한다”고 설명한다.

즉, 공간 데이터는 “위도, 경도 두 컬럼”보다 더 넓은 개념이다. 한 점을 저장하는 것에서 시작해, 선과 면까지 다룰 수 있어야 비로소 실무적인 공간 모델링이 된다.

공간 데이터는 이미 표준화되어 있다

공간 데이터는 제각각 정의하는 것이 아니라, 이미 표준이 존재한다. 발표 자료에서는 OGC(Open Geospatial Consortium)가 이러한 공간 데이터 표현 방식을 표준화해두었고, 대부분의 데이터베이스가 이 표준을 따른다고 설명한다.

이 말은 곧, MySQL의 공간 데이터 개념을 익혀두면 다른 DBMS의 공간 기능을 이해할 때도 큰 틀은 비슷하게 가져갈 수 있다는 뜻이다. 즉, 특정 제품에 종속된 지식이 아니라 지리 정보 처리 전반에 통하는 기반 개념이다.

MySQL은 어떤 공간 데이터 타입을 지원할까

MySQL은 총 7가지 공간 데이터 타입을 지원한다. 발표 자료 기준으로 핵심 타입은 다음과 같다. POINT 는 한 점, LINESTRING 은 하나의 선, POLYGON 은 하나의 면을 표현한다. 여기에 MULTIPOINT, MULTILINESTRING, MULTIPOLYGON 은 각각 여러 개의 점, 선, 면을 담을 수 있고, GEOMETRYCOLLECTION 은 이 모든 타입을 함께 담을 수 있는 집합 성격의 타입이다.

이 구조를 보면 공간 데이터 모델링이 훨씬 자연스러워진다.

  • 매장 위치: POINT
  • 러닝 코스: LINESTRING
  • 행정구역 또는 배달 가능 영역: POLYGON

즉, 데이터 의미와 저장 타입이 바로 연결된다. 일반 컬럼으로는 “이 두 숫자가 위도/경도인지”, “이 배열이 경로인지”, “이 다각형이 어떤 영역인지”를 사람이 추가로 해석해야 하지만, 공간 타입을 쓰면 스키마만 봐도 의도가 선명해진다.

SRID는 왜 중요한가

공간 데이터를 다룰 때 자주 나오는 숫자가 SRID 4326 같은 값이다. 발표에서는 SRID를 좌표계를 구분하는 식별 코드라고 설명한다. GPS 표준으로 널리 쓰이는 WGS84가 바로 SRID 4326 에 해당한다.

이 값이 왜 중요하냐면, 지구를 어떤 기준 타원체로 보고 어디를 중심으로 삼느냐에 따라 좌표값에는 차이가 생길 수 있기 때문이다. 그래서 공간 데이터는 단순히 좌표 숫자만 맞다고 끝나는 것이 아니라, 어떤 좌표계 위의 좌표인지까지 함께 맞아야 한다. 자료에서도 서로 다른 SRID를 사용하면 공간 관련 연산이 되지 않는다고 강조한다.

즉, 공간 연산에서는 “좌표값”만큼이나 “좌표계 일치”가 중요하다. 실무에서 공간 컬럼을 설계할 때는 타입만 정할 것이 아니라 SRID도 함께 통일하는 습관이 필요하다.

일반 컬럼 대신 공간 타입을 쓰면 뭐가 좋아질까

가장 큰 장점은 표현력쿼리 가독성이다.

위도(lat), 경도(lng)를 별도 컬럼으로 저장하는 방식은 단순해 보이지만, 공간 연산이 들어가는 순간 쿼리가 급격히 복잡해진다. 거리 계산, 포함 여부 판정, 겹침 여부 판단 같은 작업을 직접 수학 공식으로 표현해야 하기 때문이다. 발표 자료에서도 하버사인 공식 기반의 일반 컬럼 쿼리를 예시로 보여주며, 공간 함수 기반 쿼리에 비해 훨씬 복잡하고 직관성이 떨어진다는 점을 강조한다.

반면 공간 타입과 함수를 사용하면 “무엇을 하고 싶은지”가 함수 이름만으로 드러난다.

  • 거리 구하기: ST_DISTANCE...
  • 겹치는지 확인: ST_INTERSECTS
  • 겹치는 구간 추출: ST_INTERSECTION
  • 길이 구하기: ST_LENGTH

즉, 쿼리가 수학 계산식이 아니라 도메인 의미 중심의 문장으로 바뀐다.

예제 1: 특정 지점 반경 1km 내 건물 찾기

발표 자료의 첫 번째 예제는 잠실역을 기준으로 반경 1km 안에 있는 건물을 찾는 문제다. 이 예제에서는 buildings 테이블에 id, name, point 컬럼이 있고, point 에 위치 좌표를 저장한다. 그리고 특정 기준점도 POINT 로 만들고, 여기에 ST_SRID 로 좌표계를 지정한 뒤, ST_DISTANCE_SPHERE 계열 함수를 통해 두 점 사이 거리를 계산한다. 계산 결과가 1000m 이하인 건물만 조회하면 된다.

이 방식의 장점은 명확하다.

첫째, 기준점이 “위도와 경도 숫자 두 개”가 아니라 명시적으로 하나의 공간 객체가 된다. 둘째, 거리 계산이 수학 공식이 아니라 공간 함수 호출로 표현된다. 셋째, 쿼리만 읽어도 “이건 반경 내 검색이구나”를 파악할 수 있다.

발표 자료도 같은 문제를 일반 컬럼으로 풀었을 때 훨씬 복잡한 수식이 필요하고, 공간 데이터를 활용하는 것이 쿼리를 더 쉽게 쓸 수 있다고 정리한다.

실무에서 “근처 매장 찾기”, “반경 n km 내 게시물 보기”, “근처 러닝 모임 조회” 같은 기능은 전부 이 패턴으로 확장 가능하다.

예제 2: 러닝 코스가 특정 구역을 지나는 비율 계산하기

두 번째 예제는 훨씬 흥미롭다. 단순히 한 점과 한 점의 거리만 보는 게 아니라, 선과 면의 관계를 다룬다. 발표에서는 러닝 코스를 LINESTRING, 행정구역을 POLYGON 으로 저장한 뒤, 각 코스가 특정 구역을 어느 정도 비율로 지나가는지를 계산하는 예를 보여준다.

이 문제를 공간 함수 없이 풀려고 하면 꽤 막막하다. 선분과 다각형의 교차 여부를 직접 계산해야 하고, 겹치는 구간을 추출해야 하며, 그 길이를 전체 길이로 나누는 작업까지 전부 수학적으로 풀어야 한다.

하지만 공간 함수로는 흐름이 훨씬 명확하다.

먼저 ST_INTERSECTS 로 코스와 구역이 겹치는지 확인한다. 겹친다면 ST_INTERSECTION 으로 실제 겹치는 선분을 가져온다. 그다음 ST_LENGTH 로 겹치는 구간의 길이를 구한다. 마지막으로 전체 코스 길이로 나눠 비율을 계산한다.

이 접근은 단순히 “쿼리가 짧다”가 장점이 아니다. 문제 정의 자체가 선과 면의 관계라는 것을 SQL 수준에서 그대로 표현할 수 있다는 점이 더 중요하다.

실무적으로는 이런 계산을 통해 다음과 같은 기능을 만들 수 있다.

  • 러닝 코스의 대표 지역 자동 부여
  • 배달 경로가 어떤 구역을 얼마나 지나는지 분석
  • 특정 배송 노선의 행정구역별 커버리지 계산
  • 도로, 상권, 지역 통계 같은 지리 기반 분석

즉, 공간 데이터는 “지도 표시”를 넘어서 도메인 분석 도구로도 매우 강력하다.

MySQL만 공간 데이터를 지원하는 것은 아니다

발표 자료에서는 MySQL 외에도 PostgreSQL, MongoDB, Redis, Oracle Spatial 등 다양한 데이터베이스가 공간 데이터를 지원한다고 언급한다. 심지어 “대부분의 데이터베이스가 공간 데이터를 지원한다”는 표현도 나온다.

이 말은 곧, 공간 데이터는 특정 DB의 특수 기능이 아니라 현대 서비스에서 꽤 보편적인 데이터 모델이라는 뜻이다. 다만 각 DB마다 함수 이름, 인덱스 방식, 성능 특성은 차이가 있으므로 현재 스택에 맞게 선택하면 된다.

특히 PostgreSQL 계열에서는 PostGIS가 워낙 강력해서 공간 데이터 분야에서 자주 언급되지만, MySQL만으로도 기본적인 공간 모델링과 연산은 충분히 시작할 수 있다.

공간 데이터를 더 잘 다루려면 무엇을 더 공부해야 할까

발표 마지막에서 공간 데이터 학습 키워드로 다음 네 가지를 제시한다.

  • 공간 인덱스
  • 공간 함수
  • R-Tree
  • MBR(Minimum Bounding Rectangle)

이 네 가지는 실제 성능과 확장성 관점에서 매우 중요하다.

공간 데이터를 쿼리로만 다루기 시작하면 처음에는 재미있지만, 데이터가 많아지는 순간 “이걸 어떻게 빠르게 찾지?”라는 문제를 만나게 된다. 그때부터는 단순 함수 사용을 넘어서 공간 인덱스 구조와 탐색 전략을 이해해야 한다. 특히 반경 검색, 영역 포함 판정, 다각형 교차 판정은 인덱스를 어떻게 타느냐에 따라 성능 차이가 커질 수 있다.

즉, 공간 데이터 입문은 타입과 함수에서 시작하지만, 실무 최적화는 결국 인덱스와 검색 전략으로 이어진다.

마무리

MySQL의 공간 데이터 기능은 단순히 좌표를 예쁘게 저장하는 기능이 아니다. 점, 선, 면이라는 공간 자체를 데이터 타입으로 표현하고, 거리 계산, 교차 판정, 포함 관계, 길이 계산 같은 지리 연산을 SQL 수준에서 직접 수행할 수 있게 해준다. 발표 자료가 보여주듯, 일반 컬럼으로도 억지로 구현할 수는 있지만, 공간 타입과 함수를 쓰면 쿼리가 훨씬 더 직관적이고 간결해진다.

정리하면 이렇다.

공간 데이터의 핵심은 좌표다. 하지만 실무에서는 점만이 아니라 선과 면도 함께 다뤄야 한다. MySQL은 이를 위해 POINT, LINESTRING, POLYGON 등의 타입을 제공한다. 그리고 SRID 는 좌표계 일치를 위해 반드시 신경 써야 한다. 마지막으로 공간 함수와 인덱스를 활용하면 복잡한 지리 연산을 훨씬 자연스럽게 처리할 수 있다.

즉, 위치 기반 기능을 만들 계획이 있다면 위도/경도를 일반 숫자 컬럼으로만 다루기보다, 처음부터 공간 데이터 모델링을 검토하는 것이 장기적으로 훨씬 좋은 선택이 될 수 있다.


© 2020. All rights reserved.

SIKSIK